From 2fa788e26a8d2447be9b575111a9f7be26eaff93 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 27 Feb 2016 18:01:14 +0800 Subject: Parse - Macros in type position --- src/ast/ast.hpp | 35 +-------------------------------- src/ast/macro.hpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ src/convert/ast_iterate.cpp | 1 + src/include/debug.hpp | 1 + src/macros.hpp | 4 ++++ src/parse/lex.cpp | 1 + src/parse/lex.hpp | 4 +++- src/parse/parseerror.hpp | 1 + src/parse/tokentree.hpp | 2 +- src/parse/types.cpp | 2 ++ src/types.cpp | 25 +++++++++++++++++++++++ src/types.hpp | 10 ++++++++++ 12 files changed, 98 insertions(+), 36 deletions(-) create mode 100644 src/ast/macro.hpp 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 >; typedef Item 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 from_deserialiser(Deserialiser& s) { - auto i = new MacroInvocation; - s.item( *i ); - return ::std::unique_ptr(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 from_deserialiser(Deserialiser& s) { + auto i = new MacroInvocation; + s.item( *i ); + return ::std::unique_ptr(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 +#include 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 #include #include // 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 +#include +#include "../coretypes.hpp" #include #include 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 #include "lex.hpp" +#include 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 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 #include @@ -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): -- cgit v1.2.3