Beispiel #1
0
def construction_rename(node, scope, fname=None, index=None, depth=0):
    # NOTE to self: the depth parameter here is used exclusively to give nested
    # patterns distinguishable parameter names.

    if node.constructor not in scope:
        raise FunkyRenamingError("Constructor '{}' not " \
                                 "defined.".format(node.constructor))
    elif scope[node.constructor]["arity"] != len(node.parameters):
        raise FunkyRenamingError("Expected {} parameters for constructor " \
                                 "'{}'.".format(scope[node.constructor],
                                                node.constructor))

    localizer = get_parameter_name(fname, index, depth)
    for i, param in enumerate(node.parameters):
        if isinstance(param, Parameter):
            rename(param,
                   scope,
                   fname=node.constructor,
                   index=i,
                   localizer=localizer)
        elif isinstance(param, Construction):
            rename(param,
                   scope,
                   fname=node.constructor,
                   index=i,
                   depth=depth + 1)
        else:
            rename(param, scope)
Beispiel #2
0
def function_definition_rename(node, scope):
    if node.lhs.identifier in BUILTIN_FUNCTIONS:
        raise FunkyRenamingError(
            "Cannot redefine builtin function '{}'.".format(
                node.lhs.identifier))

    if node.lhs.identifier not in scope.local:
        if scope.is_pending_definition(node.lhs.identifier):
            newid = scope.get_pending_name(node.lhs.identifier)
            if node.lhs.identifier in scope.pending_definition:
                del scope.pending_definition[node.lhs.identifier]
        else:
            newid = get_unique_varname()
        scope[node.lhs.identifier] = {
            "id": newid,
            "arity": len(node.lhs.parameters)
        }

    tmp_scope = Scope(parent=scope)
    rename(node.lhs, tmp_scope)

    node.lhs.identifier = scope[node.lhs.identifier]["id"]

    tmp_scope2 = Scope(parent=tmp_scope)
    rename(node.rhs, tmp_scope2)

    scope.pending_definition.update(tmp_scope.pending_definition)
    scope.pending_definition.update(tmp_scope2.pending_definition)
Beispiel #3
0
def new_cons_statement_rename(node, scope):
    if node.identifier in scope:
        raise FunkyRenamingError("Duplicate definition of constructor type " \
                                 "'{}'.".format(node.identifier))
    elif node.identifier in BUILTIN_PRIMITIVES:
        raise FunkyRenamingError("Cannot define type with builtin name " \
                                 "'{}'.".format(node.identifier))

    # we don't rename the type, only the variables
    scope[node.identifier] = node.identifier

    tmp_scope_1 = Scope(parent=scope)
    for i, param in enumerate(node.type_parameters):
        tmp_scope_1[param] = get_parameter_name(node.identifier, i)

    tmp_scope_2 = Scope(parent=tmp_scope_1)
    for cons in node.constructors:
        rename(cons, tmp_scope_2)

    scope.local.update(tmp_scope_2.local)
Beispiel #4
0
def function_lhs_rename(node, scope):
    if scope[node.identifier]["arity"] != len(node.parameters):
        raise FunkyRenamingError("Definition of '{}' has different " \
                                 "number of parameters than previous " \
                                 "definition.".format(node.identifier))

    for i, param in enumerate(node.parameters):
        if isinstance(param, Parameter) or isinstance(param, Construction):
            rename(param, scope, fname=scope[node.identifier]["id"], index=i)
        else:
            rename(param, scope)
Beispiel #5
0
def pattern_definition_rename(node, scope):
    if node.variable.name in BUILTIN_FUNCTIONS:
        raise FunkyRenamingError(
            "Cannot redefine built-in function '{}'.".format(
                node.variable.name))

    rename(node.variable, scope, is_main=isinstance(node.variable, Parameter) and \
           node.variable.name == "main")

    tmp_scope = Scope(parent=scope)
    rename(node.expression, tmp_scope)
    scope.pending_definition.update(tmp_scope.pending_definition)
Beispiel #6
0
def constructor_type_rename(node, scope):
    # anything goes for the node's identifier itself -- however, the types
    # beneath it must be valid.
    if node.identifier in scope:
        raise FunkyRenamingError("Duplicate usage of constructor " \
                                 "'{}'.".format(node.identifier))

    scope[node.identifier] = {
        "id": node.identifier,
        "arity": len(node.parameters),
    }
    for i, param in enumerate(node.parameters):
        if isinstance(node, Parameter):
            rename(param, scope, fname=node.identifier, index=i)
        else:
            rename(param, scope)
Beispiel #7
0
def parameter_rename(node,
                     scope,
                     fname=None,
                     index=None,
                     localizer=None,
                     is_main=False):
    if node.name == "_": return
    if node.name in scope.local:
        raise FunkyRenamingError("Duplicate definition of parameter " \
                                 "'{}'.".format(node.name))

    if is_main:
        newid = MAIN
    elif scope.is_pending_definition(node.name):
        newid = scope.get_pending_name(node.name)
        if node.name in scope.pending_definition:
            del scope.pending_definition[node.name]
    else:
        newid = get_parameter_name(fname, localizer, index) if fname or index or \
                                                            localizer \
                else get_unique_varname()

    scope[node.name] = newid
    node.name = newid
Beispiel #8
0
def check_scope_for_errors(scope):
    err_msg = "\n".join("Referenced item '{}' was never defined.".format(ident)
                        for ident in scope.pending_definition)
    if err_msg:
        raise FunkyRenamingError(err_msg)
Beispiel #9
0
def type_rename(node, scope):
    if node.type_name not in scope and node.type_name not in BUILTIN_PRIMITIVES:
        raise FunkyRenamingError("Undefined type '{}'.".format(node.type_name))