summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/expand/cfg.cpp73
-rw-r--r--src/expand/cfg.hpp6
-rw-r--r--src/expand/mod.cpp6
-rw-r--r--src/include/span.hpp1
-rw-r--r--src/main.cpp6
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
{