diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/expand/cfg.cpp | 73 | ||||
-rw-r--r-- | src/expand/cfg.hpp | 6 | ||||
-rw-r--r-- | src/expand/mod.cpp | 6 | ||||
-rw-r--r-- | src/include/span.hpp | 1 | ||||
-rw-r--r-- | src/main.cpp | 6 |
5 files changed, 80 insertions, 12 deletions
diff --git a/src/expand/cfg.cpp b/src/expand/cfg.cpp index d178b9ae..3def0150 100644 --- a/src/expand/cfg.cpp +++ b/src/expand/cfg.cpp @@ -3,11 +3,68 @@ #include <parse/tokentree.hpp> #include <parse/lex.hpp> #include <parse/common.hpp> +#include "cfg.hpp" -bool check_cfg(const ::AST::MetaItem& mi) { - // TODO: Handle cfg conditions - throw ::std::runtime_error("TODO: Handle #[cfg] or cfg! conditions"); - return true; +#include <map> +#include <set> + +::std::map< ::std::string, ::std::string> g_cfg_values; +::std::set< ::std::string > g_cfg_flags; + +void Cfg_SetFlag(::std::string name) { + g_cfg_flags.insert( mv$(name) ); +} +void Cfg_SetValue(::std::string name, ::std::string val) { + g_cfg_values.insert( ::std::make_pair(mv$(name), mv$(name)) ); +} + +bool check_cfg(Span sp, const ::AST::MetaItem& mi) { + + if( mi.has_sub_items() ) { + // Must be `any`/`not`/`all` + if( mi.name() == "any" || mi.name() == "cfg" ) { + for(const auto& si : mi.items()) { + if( check_cfg(sp, si) ) + return true; + } + return false; + } + else if( mi.name() == "not" ) { + if( mi.items().size() != 1 ) + ERROR(sp, E0000, "cfg(not()) with != 1 argument"); + return !check_cfg(sp, mi.items()[0]); + } + else if( mi.name() == "all" ) { + for(const auto& si : mi.items()) { + if( ! check_cfg(sp, si) ) + return false; + } + return true; + } + else { + // oops + ERROR(sp, E0000, "Unknown cfg() function - " << mi.name()); + } + } + else if( mi.has_string() ) { + // Equaliy + auto it = g_cfg_values.find(mi.name()); + if( it != g_cfg_values.end() ) + { + return it->second == mi.string(); + } + else + { + WARNING(sp, W0000, "Unknown cfg() param '" << mi.name() << "'"); + return false; + } + } + else { + // Flag + auto it = g_cfg_flags.find(mi.name()); + return (it != g_cfg_flags.end()); + } + BUG(sp, "Fell off the end of check_cfg"); } class CCfgExpander: @@ -25,7 +82,7 @@ class CCfgExpander: auto attrs = Parse_MetaItem(lex); DEBUG("cfg!() - " << attrs); - if( check_cfg(attrs) ) { + if( check_cfg(sp, attrs) ) { return box$( TTStreamO(TokenTree(TOK_RWORD_TRUE )) ); } else { @@ -42,7 +99,7 @@ class CCfgHandler: void handle(const AST::MetaItem& mi, AST::Crate& crate, AST::MacroInvocation& mac) const override { - if( check_cfg(mi) ) { + if( check_cfg(mac.span(), mi) ) { // Leave as is } else { @@ -50,7 +107,7 @@ class CCfgHandler: } } void handle(const AST::MetaItem& mi, AST::Crate& crate, const AST::Path& path, AST::Module& mod, AST::Item&i) const override { - if( check_cfg(mi) ) { + if( check_cfg(Span(), mi) ) { // Leave } else { @@ -58,7 +115,7 @@ class CCfgHandler: } } void handle(const AST::MetaItem& mi, ::std::unique_ptr<AST::ExprNode>& expr) const override { - if( check_cfg(mi) ) { + if( check_cfg(Span(expr->get_pos()), mi) ) { // Leave } else { diff --git a/src/expand/cfg.hpp b/src/expand/cfg.hpp new file mode 100644 index 00000000..ae5e1054 --- /dev/null +++ b/src/expand/cfg.hpp @@ -0,0 +1,6 @@ + +#pragma once + +extern void Cfg_SetFlag(::std::string name); +extern void Cfg_SetValue(::std::string name, ::std::string val); +extern bool check_cfg(Span sp, const ::AST::MetaItem& mi); diff --git a/src/expand/mod.cpp b/src/expand/mod.cpp index 78225a2f..5ed91379 100644 --- a/src/expand/mod.cpp +++ b/src/expand/mod.cpp @@ -8,9 +8,7 @@ #include "macro_rules.hpp" #include "../parse/common.hpp" // For reparse from macros #include <ast/expr.hpp> - - -extern bool check_cfg(const ::AST::MetaItem& mi); +#include "cfg.hpp" ::std::map< ::std::string, ::std::unique_ptr<ExpandDecorator> > g_decorators; ::std::map< ::std::string, ::std::unique_ptr<ExpandProcMacro> > g_macros; @@ -47,7 +45,7 @@ void Expand_Attrs(const ::AST::MetaItems& attrs, AttrStage stage, ::std::functi for( auto& a : attrs.m_items ) { if( a.name() == "cfg_attr" ) { - if( check_cfg(a.items().at(0)) ) { + if( check_cfg(Span(), a.items().at(0)) ) { Expand_Attr(a.items().at(1), stage, f); } } diff --git a/src/include/span.hpp b/src/include/span.hpp index 05417a83..0a1033e4 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -64,6 +64,7 @@ struct Spanned }; #define ERROR(span, code, msg) do { ::Span(span).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) +#define WARNING(span, code, msg) do { ::Span(span).warning(code, [&](::std::ostream& os) { os << msg; }); } while(0) #define BUG(span, msg) do { ::Span(span).bug([&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0) #define TODO(span, msg) do { ::Span(span).bug([&](::std::ostream& os) { os << "TODO: " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0) diff --git a/src/main.cpp b/src/main.cpp index 47be9ebc..ddc233fb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,6 +15,7 @@ #include <cstring>
#include <main_bindings.hpp>
+#include "expand/cfg.hpp"
int g_debug_indent_level = 0;
::std::string g_cur_phase;
@@ -70,6 +71,11 @@ int main(int argc, char *argv[]) ProgramParams params(argc, argv);
+ // Set up cfg values
+ Cfg_SetFlag("linux");
+ Cfg_SetValue("target_pointer_width", "64");
+
+
try
{
|