expel / 9023ed3 include / expel / resolve.h

Tree @9023ed3 (Download .tar.gz)

resolve.h @9023ed3raw · history · blame

 * resolve.h: name resolution at compile time
 * Copyright (C) 2016, Haldean Brown
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

#pragma once
#include "expel/expel.h"
#include "expel/ast.h"
#include "expel/vector.h"

enum xl_resolve_type
        /* if a name resolves locally, then the name should be accessed by using
         * a ref node to the appropriate node for the name. */
        RESOLVE_LOCAL = 1,
        /* if a name resolves globally, then the name should be accessed by
         * using a load node with the userdef scope. */
        /* if a name resolves through closure, then the ast needs to be
         * transformed such that the name can be accessed as a local. */

struct xl_resolve_name
        char *name;
        enum xl_resolve_type type;
        struct xl_dagc_node *node;

struct xl_resolve_name_loc
        enum xl_resolve_type type;

/* Scope boundaries are used to determine whether something is
 * accessible in the current scope or not; it is useful for the closure
 * transformation to know about things in enclosing but inaccessible
 * scopes. If a scope has a BOUNDARY_BLOCK boundary type, then its
 * parent is accessible (as it's just a scope object inside another
 * scope). If a scope has a BOUNDARY_FUNCTION boundary type, its parent
 * is not accessible as they exist in separate functions, and we need to
 * close over its parents' values. If a scope has a BOUNDARY_GLOBAL boundary
 * type, its members can be accessed using load nodes instead of ref nodes and
 * thus they don't have to be closed over. */
enum xl_resolve_boundary_type
        BOUNDARY_BLOCK = 1,

struct xl_resolve_scope
        /* members of are struct xl_resolve_name pointers */
        struct xl_vector names;

        struct xl_resolve_scope *parent;
        enum xl_resolve_boundary_type boundary;

        /* This thing is complicated. There's a long explanation in closure.c
         * about what it means. Go read that. */
        bool needs_closure_appl;

enum xl_resolve_error_type

struct xl_resolve_error
        enum xl_resolve_error_type err_type;
        char *name;

struct xl_resolve_context
        struct xl_resolve_scope *native_scope;
        struct xl_vector scope_allocs;
        struct xl_vector allocs;
        struct xl_vector errors;

no_ignore xl_error
        struct xl_ast *ast,
        char *source_name,
        struct xl_resolve_context *ctx);

xl_resolve_context_free(struct xl_resolve_context *ctx);