105 lines
2.6 KiB
C++
105 lines
2.6 KiB
C++
/*
|
|
* Copyright (C) 2014 Patrick Mours
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "effect_module.hpp"
|
|
#include <cstdint>
|
|
#include <unordered_map> // Used for symbol lookup table
|
|
|
|
namespace reshadefx
|
|
{
|
|
/// <summary>
|
|
/// A scope encapsulating symbols.
|
|
/// </summary>
|
|
struct scope
|
|
{
|
|
std::string name;
|
|
uint32_t level, namespace_level;
|
|
};
|
|
|
|
/// <summary>
|
|
/// Enumeration of all possible symbol types.
|
|
/// </summary>
|
|
enum class symbol_type
|
|
{
|
|
invalid,
|
|
variable,
|
|
constant,
|
|
function,
|
|
intrinsic,
|
|
structure,
|
|
};
|
|
|
|
/// <summary>
|
|
/// A single symbol in the symbol table.
|
|
/// </summary>
|
|
struct symbol
|
|
{
|
|
symbol_type op = symbol_type::invalid;
|
|
uint32_t id = 0;
|
|
reshadefx::type type = {};
|
|
reshadefx::constant constant = {};
|
|
const reshadefx::function *function = nullptr;
|
|
};
|
|
struct scoped_symbol : symbol
|
|
{
|
|
struct scope scope; // Store scope together with symbol data
|
|
};
|
|
|
|
/// <summary>
|
|
/// A symbol table managing a list of scopes and symbols.
|
|
/// </summary>
|
|
class symbol_table
|
|
{
|
|
public:
|
|
symbol_table();
|
|
|
|
/// <summary>
|
|
/// Enters a new scope as child of the current one.
|
|
/// </summary>
|
|
void enter_scope();
|
|
/// <summary>
|
|
/// Enters a new namespace as child of the current one.
|
|
/// </summary>
|
|
void enter_namespace(const std::string &name);
|
|
/// <summary>
|
|
/// Leaves the current scope and enter the parent one.
|
|
/// </summary>
|
|
void leave_scope();
|
|
/// <summary>
|
|
/// Leaves the current namespace and enter the parent one.
|
|
/// </summary>
|
|
void leave_namespace();
|
|
|
|
/// <summary>
|
|
/// Gets the current scope the symbol table operates in.
|
|
/// </summary>
|
|
const scope ¤t_scope() const { return _current_scope; }
|
|
|
|
/// <summary>
|
|
/// Inserts an new symbol in the symbol table.
|
|
/// Returns <see langword="false"/> if a symbol by that name and type already exists.
|
|
/// </summary>
|
|
bool insert_symbol(const std::string &name, const symbol &symbol, bool global = false);
|
|
|
|
/// <summary>
|
|
/// Looks for an existing symbol with the specified <paramref name="name"/>.
|
|
/// </summary>
|
|
scoped_symbol find_symbol(const std::string &name) const;
|
|
scoped_symbol find_symbol(const std::string &name, const scope &scope, bool exclusive) const;
|
|
|
|
/// <summary>
|
|
/// Searches for the best function or intrinsic overload matching the argument list.
|
|
/// </summary>
|
|
bool resolve_function_call(const std::string &name, const std::vector<expression> &args, const scope &scope, symbol &data, bool &ambiguous) const;
|
|
|
|
private:
|
|
scope _current_scope;
|
|
// Lookup table from name to matching symbols
|
|
std::unordered_map<std::string, std::vector<scoped_symbol>> _symbol_stack;
|
|
};
|
|
}
|