diff options
author | John Hodge <tpg@mutabah.net> | 2016-02-27 18:01:14 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2016-02-27 18:01:14 +0800 |
commit | 2fa788e26a8d2447be9b575111a9f7be26eaff93 (patch) | |
tree | fadde986d721b178917ab1bd9a5219075670668e | |
parent | df62d33afdb267465caabf91abf340ce4884c443 (diff) | |
download | mrust-2fa788e26a8d2447be9b575111a9f7be26eaff93.tar.gz |
Parse - Macros in type position
-rw-r--r-- | src/ast/ast.hpp | 35 | ||||
-rw-r--r-- | src/ast/macro.hpp | 48 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 1 | ||||
-rw-r--r-- | src/include/debug.hpp | 1 | ||||
-rw-r--r-- | src/macros.hpp | 4 | ||||
-rw-r--r-- | src/parse/lex.cpp | 1 | ||||
-rw-r--r-- | src/parse/lex.hpp | 4 | ||||
-rw-r--r-- | src/parse/parseerror.hpp | 1 | ||||
-rw-r--r-- | src/parse/tokentree.hpp | 2 | ||||
-rw-r--r-- | src/parse/types.cpp | 2 | ||||
-rw-r--r-- | src/types.cpp | 25 | ||||
-rw-r--r-- | src/types.hpp | 10 |
12 files changed, 98 insertions, 36 deletions
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 2aea5ac1..3e8ee259 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -24,6 +24,7 @@ #include "pattern.hpp"
#include "attrs.hpp"
#include "expr.hpp"
+#include "macro.hpp"
namespace AST {
@@ -214,40 +215,6 @@ using ItemList = ::std::vector<Item<T> >; typedef Item<TypeRef> StructItem;
class Crate;
-class MacroInvocation:
- public Serialisable
-{
- MetaItems m_attrs;
- ::std::string m_macro_name;
- ::std::string m_ident;
- TokenTree m_input;
-public:
- MacroInvocation()
- {
- }
-
- MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input):
- m_attrs( mv$(attrs) ),
- m_macro_name( mv$(macro) ),
- m_ident( mv$(ident) ),
- m_input( mv$(input) )
- {
- }
-
- static ::std::unique_ptr<MacroInvocation> from_deserialiser(Deserialiser& s) {
- auto i = new MacroInvocation;
- s.item( *i );
- return ::std::unique_ptr<MacroInvocation>(i);
- }
-
- SERIALISABLE_PROTOTYPES();
-
- friend ::std::ostream& operator<<(::std::ostream& os, const MacroInvocation& x) {
- os << x.m_attrs << x.m_macro_name << "! " << x.m_ident << x.m_input;
- return os;
- }
-};
-
class TypeAlias:
public Serialisable
{
diff --git a/src/ast/macro.hpp b/src/ast/macro.hpp new file mode 100644 index 00000000..d80db7bf --- /dev/null +++ b/src/ast/macro.hpp @@ -0,0 +1,48 @@ + +#ifndef _AST_MACRO_HPP_ +#define _AST_MACRO_HPP_ + +#include "../parse/tokentree.hpp" +#include "attrs.hpp" + +namespace AST { + +class MacroInvocation: + public Serialisable +{ + ::AST::MetaItems m_attrs; + ::std::string m_macro_name; + ::std::string m_ident; + TokenTree m_input; +public: + MacroInvocation() + { + } + + MacroInvocation(MetaItems attrs, ::std::string macro, ::std::string ident, TokenTree input): + m_attrs( mv$(attrs) ), + m_macro_name( mv$(macro) ), + m_ident( mv$(ident) ), + m_input( mv$(input) ) + { + } + + static ::std::unique_ptr<MacroInvocation> from_deserialiser(Deserialiser& s) { + auto i = new MacroInvocation; + s.item( *i ); + return ::std::unique_ptr<MacroInvocation>(i); + } + + SERIALISABLE_PROTOTYPES(); + + friend ::std::ostream& operator<<(::std::ostream& os, const MacroInvocation& x) { + os << x.m_attrs << x.m_macro_name << "! " << x.m_ident << x.m_input; + return os; + } +}; + + +} + +#endif + diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp index 3bee3234..2e1dfe23 100644 --- a/src/convert/ast_iterate.cpp +++ b/src/convert/ast_iterate.cpp @@ -14,6 +14,7 @@ void CASTIterator::handle_type(TypeRef& type) (None), (Any), (Unit), + (Macro), (Primitive), (Path, handle_path(ent.path, MODE_TYPE); diff --git a/src/include/debug.hpp b/src/include/debug.hpp index b8c54440..e1dedb7b 100644 --- a/src/include/debug.hpp +++ b/src/include/debug.hpp @@ -2,6 +2,7 @@ */ #pragma once #include <sstream> +#include <cassert> extern int g_debug_indent_level; diff --git a/src/macros.hpp b/src/macros.hpp index b28370d9..d7efec1a 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -9,6 +9,10 @@ class MacroExpander;
+namespace AST {
+ class Module;
+}
+
class MacroRuleEnt:
public Serialisable
{
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 32ed8829..829a62de 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -13,6 +13,7 @@ #include "lex.hpp" #include "tokentree.hpp" #include "parseerror.hpp" +#include "../common.hpp" #include <cassert> #include <iostream> #include <cstdlib> // strtol diff --git a/src/parse/lex.hpp b/src/parse/lex.hpp index 937be516..0dc94d12 100644 --- a/src/parse/lex.hpp +++ b/src/parse/lex.hpp @@ -8,7 +8,9 @@ #ifndef LEX_HPP_INCLUDED #define LEX_HPP_INCLUDED -#include "../types.hpp" +#include <debug.hpp> +#include <serialise.hpp> +#include "../coretypes.hpp" #include <string> #include <fstream> diff --git a/src/parse/parseerror.hpp b/src/parse/parseerror.hpp index 751af585..1074bf46 100644 --- a/src/parse/parseerror.hpp +++ b/src/parse/parseerror.hpp @@ -3,6 +3,7 @@ #include <stdexcept>
#include "lex.hpp"
+#include <compile_error.hpp>
namespace ParseError {
diff --git a/src/parse/tokentree.hpp b/src/parse/tokentree.hpp index aa72a522..6b54e66e 100644 --- a/src/parse/tokentree.hpp +++ b/src/parse/tokentree.hpp @@ -2,7 +2,7 @@ #define TOKENTREE_HPP_INCLUDED
#include "lex.hpp"
-
+#include "../include/serialise.hpp"
class TokenTree:
public Serialisable
diff --git a/src/parse/types.cpp b/src/parse/types.cpp index 33307dea..7b69dbd6 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -33,6 +33,8 @@ TypeRef Parse_Type_Int(TokenStream& lex) switch( GET_TOK(tok, lex) ) { + case TOK_MACRO: + return TypeRef(TypeRef::TagMacro(), Parse_MacroInvocation(AST::MetaItems(), mv$(tok.str()), lex)); // '!' - Only ever used as part of function prototypes, but is kinda a type... not allowed here though case TOK_EXCLAM: throw ParseError::Generic(lex, "! is not a real type"); diff --git a/src/types.cpp b/src/types.cpp index 882caef5..454ed801 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -101,6 +101,7 @@ bool TypeRef::deref(bool is_implicit) switch(m_data.tag()) { case TypeData::TAG_None: throw ::std::runtime_error("Dereferencing ! - bugcheck"); + case TypeData::TAG_Macro: throw ::std::runtime_error("Dereferencing unexpanded macro - bugcheck"); case TypeData::TAG_Any: throw ::std::runtime_error("Dereferencing _"); case TypeData::TAG_Unit: throw ::std::runtime_error("Dereferencing ()"); case TypeData::TAG_Primitive: throw ::std::runtime_error("Dereferencing a primtive type"); @@ -167,6 +168,9 @@ void TypeRef::merge_with(const TypeRef& other) (None, throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard"); ), + (Macro, + throw ::std::runtime_error("TypeRef::merge_with - Reached unexpanded macro"); + ), (Any, throw ::std::runtime_error("TypeRef::merge_with - Reached concrete/wildcard"); ), @@ -233,6 +237,9 @@ void TypeRef::resolve_args(::std::function<TypeRef(const char*)> fcn) _(None, throw ::std::runtime_error("TypeRef::resolve_args on !"); ) + _(Macro, + throw ::std::runtime_error("TypeRef::resolve_args on unexpanded macro"); + ) // TODO: Is resolving args on an ANY an erorr? _(Any) _(Unit) @@ -296,6 +303,9 @@ void TypeRef::match_args(const TypeRef& other, ::std::function<void(const char*, (None, throw ::std::runtime_error("TypeRef::match_args on !"); ), + (Macro, + throw CompileError::BugCheck("TypeRef::match_args - unexpanded macro"); + ), (Any, // Wait, isn't this an error? throw ::std::runtime_error("Encountered '_' in match_args"); @@ -357,6 +367,9 @@ bool TypeRef::impls_wildcard(const AST::Crate& crate, const AST::Path& trait) co (None, throw CompileError::BugCheck("TypeRef::impls_wildcard on !"); ), + (Macro, + throw CompileError::BugCheck("TypeRef::impls_wildcard - unexpanded macro"); + ), (Any, throw CompileError::BugCheck("TypeRef::impls_wildcard on _"); ), @@ -450,6 +463,7 @@ bool TypeRef::is_concrete() const (None, throw ::std::runtime_error("TypeRef::is_concrete on !"); ), + (Macro, throw CompileError::BugCheck("TypeRef::is_concrete - unexpanded macro");), (Any, return false;), (Unit, return true; ), (Primitive, return true; ), @@ -503,6 +517,7 @@ int TypeRef::equal_no_generic(const TypeRef& x) const TU_MATCH(TypeData, (m_data, x.m_data), (ent, x_ent), (None, return 0;), + (Macro, throw CompileError::BugCheck("TypeRef::equal_no_generic - unexpanded macro");), (Unit, return 0;), (Any, return 0;), (Primitive, @@ -561,6 +576,7 @@ Ordering TypeRef::ord(const TypeRef& x) const TU_MATCH(TypeData, (m_data, x.m_data), (ent, x_ent), (None, return OrdEqual;), + (Macro, throw CompileError::BugCheck("TypeRef::ord - unexpanded macro");), (Any, return OrdEqual;), (Unit, return OrdEqual;), (Primitive, @@ -629,6 +645,9 @@ Ordering TypeRef::ord(const TypeRef& x) const _(Any, os << "_"; ) + _(Macro, + os << ent.inv; + ) _(Unit, os << "()"; ) @@ -732,6 +751,9 @@ SERIALISE_TYPE(TypeRef::, "TypeRef", { switch(m_data.tag()) { _S(None) + _S(Macro, + s.item( ent.inv ); + ) _S(Any) _S(Unit) _S(Primitive, @@ -778,6 +800,9 @@ SERIALISE_TYPE(TypeRef::, "TypeRef", { _D(None) _D(Any) _D(Unit) + _D(Macro, + s.item( ent.inv ); + ) _D(Primitive, s % ent.core_type; ) diff --git a/src/types.hpp b/src/types.hpp index 0cb8ba9a..24c0d9ea 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -6,6 +6,7 @@ #include "common.hpp"
#include "coretypes.hpp"
#include "ast/path.hpp"
+#include "ast/macro.hpp"
#include <serialise.hpp>
#include <tagged_union.hpp>
@@ -60,6 +61,9 @@ TAGGED_UNION(TypeData, None, (None, ()),
(Any, ()),
(Unit, ()),
+ (Macro, (
+ ::AST::MacroInvocation inv;
+ )),
(Primitive, (
enum eCoreType core_type;
)),
@@ -115,6 +119,7 @@ public: #define _CLONE(VAR, code...) case TypeData::TAG_##VAR: { auto& old = other.m_data.as_##VAR(); m_data = TypeData::make_##VAR(code); } break;
_COPY(None)
_COPY(Any)
+ _COPY(Macro)
_COPY(Unit)
_COPY(Primitive)
_COPY(Function)
@@ -142,6 +147,11 @@ public: TypeRef(TagInvalid):
m_data(TypeData::make_None({}))
{}
+
+ struct TagMacro {};
+ TypeRef(TagMacro, ::AST::MacroInvocation inv):
+ m_data(TypeData::make_Macro({mv$(inv)}))
+ {}
struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
TypeRef(TagUnit):
|