69 lines
2.0 KiB
C++
69 lines
2.0 KiB
C++
// Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
|
|
|
|
#pragma once
|
|
|
|
#include <map>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include <hilti/base/result.h>
|
|
|
|
namespace hilti::util {
|
|
/**
|
|
* Helper to preprocess @if/@else/@endif directives in lines of input.
|
|
*
|
|
* This currently supports the following set of directives:
|
|
*
|
|
* - `@if [!] <id> ==|!=|<|<=|>|>= <integer>
|
|
* - `@if [!] <id>
|
|
* - `@else`
|
|
* - `@endif`
|
|
**/
|
|
class SourceCodePreprocessor {
|
|
public:
|
|
using ID = std::string; //< type for identifiers
|
|
using Value = int; //< type associated with integers (may expand this to a variant in the future)
|
|
|
|
/** Current inclusion state while processing input. */
|
|
enum class State {
|
|
Include, //< include line
|
|
Skip //< skip line
|
|
};
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param constants map of constants that preprocessor directives can work on
|
|
*/
|
|
SourceCodePreprocessor(std::map<ID, Value> constants) : _constants(std::move(std::move(constants))) {}
|
|
|
|
/**
|
|
* Process one preprocessor directive of the form `@<id> [expression]`.
|
|
*
|
|
* This evaluates the directive and updates internal state accordingly.
|
|
*
|
|
* @param directive a supported directive ID, which must start with `@`.
|
|
* @param expression string with expression that the directive is taking
|
|
* @result the new inclusion state for subsequent input, or an error if the directive could not be processed
|
|
*/
|
|
Result<State> processLine(std::string_view directive, std::string_view expression = "");
|
|
|
|
/** Returns the current inclusion state. */
|
|
State state() const { return _stack.back() == 1 ? State::Include : State::Skip; }
|
|
|
|
/**
|
|
* Returns true if the proprocessor expects further directives that closed
|
|
* previously opened blocks
|
|
*/
|
|
bool expectingDirective() { return _stack.size() > 1; }
|
|
|
|
private:
|
|
Result<bool> _parseIf(const std::string_view& expression);
|
|
|
|
std::map<ID, Value> _constants;
|
|
std::vector<int> _stack = {1};
|
|
};
|
|
|
|
} // namespace hilti::util
|