diff options
-rw-r--r-- | ast/ast.cpp | 28 | ||||
-rw-r--r-- | ast/ast.hpp | 27 | ||||
-rw-r--r-- | main.cpp | 10 | ||||
-rw-r--r-- | parse/common.hpp | 35 | ||||
-rw-r--r-- | parse/expr.cpp | 31 | ||||
-rw-r--r-- | parse/lex.cpp | 8 | ||||
-rw-r--r-- | parse/lex.hpp | 4 | ||||
-rw-r--r-- | parse/root.cpp | 249 | ||||
-rw-r--r-- | types.hpp | 4 |
9 files changed, 302 insertions, 94 deletions
diff --git a/ast/ast.cpp b/ast/ast.cpp index bf86649b..1683bf91 100644 --- a/ast/ast.cpp +++ b/ast/ast.cpp @@ -13,11 +13,17 @@ Path::Path(Path::TagAbsolute) {
}
+
+PathNode::PathNode(::std::string name, ::std::vector<TypeRef> args):
+ m_name(name),
+ m_params(args)
+{
+}
const ::std::string& PathNode::name() const
{
return m_name;
}
-const TypeParams& PathNode::args() const
+const ::std::vector<TypeRef>& PathNode::args() const
{
return m_params;
}
@@ -28,6 +34,21 @@ Pattern::Pattern(TagMaybeBind, ::std::string name) Pattern::Pattern(TagValue, ExprNode node)
{
}
+Pattern::Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns)
+{
+}
+
+
+Function::Function(::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code)
+{
+}
+
+Impl::Impl(TypeRef impl_type, TypeRef trait_type)
+{
+}
+void Impl::add_function(bool is_public, Function fcn)
+{
+}
void Module::add_constant(bool is_public, ::std::string name, TypeRef type, Expr val)
{
@@ -41,7 +62,10 @@ void Module::add_global(bool is_public, bool is_mut, ::std::string name, TypeRef void Module::add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items)
{
}
-void Module::add_function(bool is_public, ::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code)
+void Module::add_function(bool is_public, Function func)
+{
+}
+void Module::add_impl(Impl impl)
{
}
diff --git a/ast/ast.hpp b/ast/ast.hpp index cfdf23e4..ab5f73f5 100644 --- a/ast/ast.hpp +++ b/ast/ast.hpp @@ -26,10 +26,11 @@ typedef ::std::pair< ::std::string, TypeRef> StructItem; class PathNode
{
::std::string m_name;
- TypeParams m_params;
+ ::std::vector<TypeRef> m_params;
public:
+ PathNode(::std::string name, ::std::vector<TypeRef> args);
const ::std::string& name() const;
- const TypeParams& args() const;
+ const ::std::vector<TypeRef>& args() const;
};
class Path
@@ -39,7 +40,7 @@ public: struct TagAbsolute {};
Path(TagAbsolute);
- void append(::std::string str) {}
+ void append(PathNode node) {}
size_t length() const {return 0;}
PathNode& operator[](size_t idx) { throw ::std::out_of_range("Path []"); }
@@ -55,6 +56,9 @@ public: struct TagValue {};
Pattern(TagValue, ExprNode node);
+
+ struct TagEnumVariant {};
+ Pattern(TagEnumVariant, Path path, ::std::vector<Pattern> sub_patterns);
};
class ExprNode
@@ -88,6 +92,20 @@ public: Expr(ExprNode node) {}
};
+class Function
+{
+public:
+ Function(::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code);
+};
+
+class Impl
+{
+public:
+ Impl(TypeRef impl_type, TypeRef trait_type);
+
+ void add_function(bool is_public, Function fcn);
+};
+
class Module
{
public:
@@ -95,7 +113,8 @@ public: void add_constant(bool is_public, ::std::string name, TypeRef type, Expr val);
void add_global(bool is_public, bool is_mut, ::std::string name, TypeRef type, Expr val);
void add_struct(bool is_public, ::std::string name, TypeParams params, ::std::vector<StructItem> items);
- void add_function(bool is_public, ::std::string name, TypeParams params, TypeRef ret_type, ::std::vector<StructItem> args, Expr code);
+ void add_function(bool is_public, Function func);
+ void add_impl(Impl impl);
};
}
@@ -1,5 +1,6 @@ #include <iostream>
#include "parse/lex.hpp"
+#include "parse/parseerror.hpp"
using namespace std;
@@ -7,6 +8,13 @@ extern void Parse_Crate(::std::string mainfile); int main(int argc, char *argv[])
{
- Parse_Crate("samples/1.rs");
+ try
+ {
+ Parse_Crate("samples/1.rs");
+ }
+ catch(const ParseError::Base& e)
+ {
+ ::std::cerr << "Parser Error: " << e.what() << ::std::endl;
+ }
return 0;
}
diff --git a/parse/common.hpp b/parse/common.hpp index 211fadee..0d6d550b 100644 --- a/parse/common.hpp +++ b/parse/common.hpp @@ -1,5 +1,6 @@ #ifndef PARSE_COMMON_HPP_INCLUDED
-#define PARSEERROR_HPP_INCLUDED
+#define PARSE_COMMON_HPP_INCLUDED
+#include <iostream>
#define GET_TOK(tok, lex) ((tok = lex.getToken()).type())
#define GET_CHECK_TOK(tok, lex, exp) do {\
@@ -11,9 +12,39 @@ throw ParseError::Unexpected(tok, Token(exp));\
} while(0)
-extern AST::Path Parse_Path(TokenStream& lex, bool is_abs, bool generic_ok);
+enum eParsePathGenericMode
+{
+ PATH_GENERIC_NONE,
+ PATH_GENERIC_EXPR,
+ PATH_GENERIC_TYPE
+};
+
+extern AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generic_mode);
extern TypeRef Parse_Type(TokenStream& lex);
extern AST::Expr Parse_Expr(TokenStream& lex, bool const_only);
extern AST::Expr Parse_ExprBlock(TokenStream& lex);
+class TraceLog
+{
+ static unsigned int depth;
+ const char* m_tag;
+public:
+ TraceLog(const char* tag): m_tag(tag) { indent(); ::std::cout << ">> " << m_tag << ::std::endl; }
+ ~TraceLog() { outdent(); ::std::cout << "<< " << m_tag << ::std::endl; }
+private:
+ void indent()
+ {
+ for(unsigned int i = 0; i < depth; i ++)
+ ::std::cout << " ";
+ depth ++;
+ }
+ void outdent()
+ {
+ depth --;
+ for(unsigned int i = 0; i < depth; i ++)
+ ::std::cout << " ";
+ }
+};
+#define TRACE_FUNCTION TraceLog _tf_(__func__)
+
#endif // PARSE_COMMON_HPP_INCLUDED
diff --git a/parse/expr.cpp b/parse/expr.cpp index 3c6e2199..90a39b04 100644 --- a/parse/expr.cpp +++ b/parse/expr.cpp @@ -39,7 +39,7 @@ AST::Pattern Parse_Pattern(TokenStream& lex) // 1. Identifiers could be either a bind or a value
// - If the path resolves to a single node, either a local enum value, or a binding
lex.putback(tok);
- path = Parse_Path(lex, false, true);
+ path = Parse_Path(lex, false, PATH_GENERIC_EXPR);
if( path.length() == 1 && path[0].args().size() == 0 )
{
// Could be a name binding, check the next token
@@ -56,13 +56,20 @@ AST::Pattern Parse_Pattern(TokenStream& lex) // 2. Paths are enum/struct names
{
lex.putback(tok);
- path = Parse_Path(lex, true, true);
+ path = Parse_Path(lex, true, PATH_GENERIC_EXPR);
}
switch( GET_TOK(tok, lex) )
{
- case TOK_PAREN_OPEN:
+ case TOK_PAREN_OPEN: {
// A list of internal patterns
- throw ParseError::Todo("nested patterns");
+ ::std::vector<AST::Pattern> child_pats;
+ do {
+ AST::Pattern pat = Parse_Pattern(lex);
+ child_pats.push_back(pat);
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ return AST::Pattern(AST::Pattern::TagEnumVariant(), path, child_pats);
+ }
default:
lex.putback(tok);
return AST::Pattern(AST::Pattern::TagValue(), ExprNode(ExprNode::TagNamedValue(), path));
@@ -70,6 +77,8 @@ AST::Pattern Parse_Pattern(TokenStream& lex) break;
case TOK_INTEGER:
return AST::Pattern( AST::Pattern::TagValue(), ExprNode(ExprNode::TagInteger(), tok.intval(), tok.datatype()) );
+ case TOK_PAREN_OPEN:
+ throw ParseError::Todo("tuple patterns");
default:
throw ParseError::Unexpected(tok);
}
@@ -177,10 +186,10 @@ AST::ExprNode Parse_ExprBlocks(TokenStream& lex) AST::ExprNode switch_val = Parse_Expr1(lex);
GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
::std::vector< ::std::pair<AST::Pattern, ExprNode> > arms;
- if( (tok = lex.getToken()).type() == TOK_BRACE_CLOSE )
- throw ParseError::Unexpected(tok, Token(TOK_BRACE_CLOSE));
- lex.putback(tok);
do {
+ if( GET_TOK(tok, lex) == TOK_BRACE_CLOSE )
+ break;
+ lex.putback(tok);
AST::Pattern pat = Parse_Pattern(lex);
GET_CHECK_TOK(tok, lex, TOK_FATARROW);
AST::ExprNode val = Parse_Expr0(lex);
@@ -232,7 +241,7 @@ LEFTASSOC(Parse_Expr2, Parse_Expr3, LEFTASSOC(Parse_Expr3, Parse_Expr4,
case TOK_DOUBLE_EQUAL:
throw ParseError::Todo("expr - equal");
- case TOK_EXLAM_EQUAL:
+ case TOK_EXCLAM_EQUAL:
throw ParseError::Todo("expr - not equal");
)
// 4: Comparisons
@@ -298,7 +307,7 @@ AST::ExprNode Parse_Expr12(TokenStream& lex) {
case TOK_DASH:
throw ParseError::Todo("expr - negate");
- case TOK_EXLAM:
+ case TOK_EXCLAM:
throw ParseError::Todo("expr - logical negate");
case TOK_STAR:
throw ParseError::Todo("expr - dereference");
@@ -345,10 +354,10 @@ AST::ExprNode Parse_ExprVal(TokenStream& lex) case TOK_IDENT:
// Get path
lex.putback(tok);
- path = Parse_Path(lex, false, true);
+ path = Parse_Path(lex, false, PATH_GENERIC_EXPR);
if(0)
case TOK_DOUBLE_COLON:
- path = Parse_Path(lex, true, true);
+ path = Parse_Path(lex, true, PATH_GENERIC_EXPR);
switch( GET_TOK(tok, lex) )
{
case TOK_BRACE_OPEN:
diff --git a/parse/lex.cpp b/parse/lex.cpp index 2c6d42df..99568a11 100644 --- a/parse/lex.cpp +++ b/parse/lex.cpp @@ -33,8 +33,8 @@ static const struct { const char* chars;
signed int type;
} TOKENMAP[] = {
- TOKENT("!" , TOK_EXLAM),
- TOKENT("!=", TOK_EXLAM_EQUAL),
+ TOKENT("!" , TOK_EXCLAM),
+ TOKENT("!=", TOK_EXCLAM_EQUAL),
TOKENT("\"", DOUBLEQUOTE),
TOKENT("#", 0),
TOKENT("#![",TOK_CATTR_OPEN),
@@ -437,7 +437,7 @@ const char* Token::typestr(enum eTokenType type) case TOK_THINARROW: return "TOK_THINARROW"; // ->
case TOK_PLUS: return "TOK_PLUS"; case TOK_DASH: return "TOK_DASH";
- case TOK_EXLAM: return "TOK_EXLAM";
+ case TOK_EXCLAM: return "TOK_EXCLAM";
case TOK_PERCENT: return "TOK_PERCENT";
case TOK_SLASH: return "TOK_SLASH";
@@ -455,7 +455,7 @@ const char* Token::typestr(enum eTokenType type) case TOK_PIPE_EQUAL: return "TOK_PIPE_EQUAL";
case TOK_DOUBLE_EQUAL: return "TOK_DOUBLE_EQUAL";
- case TOK_EXLAM_EQUAL: return "TOK_EXLAM_EQUAL";
+ case TOK_EXCLAM_EQUAL: return "TOK_EXCLAM_EQUAL";
case TOK_GTE: return "TOK_GTE";
case TOK_LTE: return "TOK_LTE";
diff --git a/parse/lex.hpp b/parse/lex.hpp index 3dff4d3a..a219ae94 100644 --- a/parse/lex.hpp +++ b/parse/lex.hpp @@ -41,7 +41,7 @@ enum eTokenType TOK_THINARROW, // ->
TOK_PLUS, TOK_DASH,
- TOK_EXLAM,
+ TOK_EXCLAM,
TOK_PERCENT,
TOK_SLASH,
@@ -59,7 +59,7 @@ enum eTokenType TOK_PIPE_EQUAL,
TOK_DOUBLE_EQUAL,
- TOK_EXLAM_EQUAL,
+ TOK_EXCLAM_EQUAL,
TOK_GTE,
TOK_LTE,
diff --git a/parse/root.cpp b/parse/root.cpp index 642c538c..c82527a2 100644 --- a/parse/root.cpp +++ b/parse/root.cpp @@ -6,32 +6,69 @@ #include "common.hpp"
#include <cassert>
-AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, bool generic_ok)
+unsigned int TraceLog::depth = 0;
+
+::std::vector<TypeRef> Parse_Path_GenericList(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
+ ::std::vector<TypeRef> types;
+ Token tok;
+ do {
+ types.push_back( Parse_Type(lex) );
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_GT);
+ return types;
+}
+
+AST::Path Parse_PathFrom(TokenStream& lex, AST::Path path, eParsePathGenericMode generic_mode)
+{
+ TRACE_FUNCTION;
+
Token tok;
- do
+
+ tok = lex.getToken();
+ while(true)
{
+ ::std::vector<TypeRef> params;
+
+ CHECK_TOK(tok, TOK_IDENT);
+ ::std::string component = tok.str();
+
tok = lex.getToken();
- if(tok.type() == TOK_LT)
+ if(generic_mode == PATH_GENERIC_TYPE && tok.type() == TOK_LT)
{
- throw ParseError::Todo("Parse_Path - Generics");
+ // Type-mode generics "::path::to::Type<A,B>"
+ params = Parse_Path_GenericList(lex);
+ tok = lex.getToken();
+ }
+ if( tok.type() != TOK_DOUBLE_COLON ) {
+ path.append( AST::PathNode(component, params) );
+ break;
}
-
- if(tok.type() != TOK_IDENT)
- throw ParseError::Unexpected(tok);
- path.append( tok.str() );
tok = lex.getToken();
- } while( tok.type() == TOK_DOUBLE_COLON );
+ if( generic_mode == PATH_GENERIC_EXPR && tok.type() == TOK_LT )
+ {
+ // Expr-mode generics "::path::to::function::<Type1,Type2>(arg1, arg2)"
+ params = Parse_Path_GenericList(lex);
+ tok = lex.getToken();
+ if( tok.type() != TOK_DOUBLE_COLON ) {
+ path.append( AST::PathNode(component, params) );
+ break;
+ }
+ }
+ path.append( AST::PathNode(component, params) );
+ }
lex.putback(tok);
return path;
}
-AST::Path Parse_Path(TokenStream& lex, bool is_abs, bool generic_ok)
+AST::Path Parse_Path(TokenStream& lex, bool is_abs, eParsePathGenericMode generic_mode)
{
if( is_abs )
- return Parse_PathFrom(lex, AST::Path(AST::Path::TagAbsolute()), generic_ok);
+ return Parse_PathFrom(lex, AST::Path(AST::Path::TagAbsolute()), generic_mode);
else
- return Parse_PathFrom(lex, AST::Path(), generic_ok);
+ return Parse_PathFrom(lex, AST::Path(), generic_mode);
}
static const struct {
@@ -55,6 +92,8 @@ static const struct { TypeRef Parse_Type(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
Token tok = lex.getToken();
switch(tok.type())
{
@@ -71,11 +110,10 @@ TypeRef Parse_Type(TokenStream& lex) }
// or a primitive
lex.putback(tok);
- return TypeRef(TypeRef::TagPath(), Parse_Path(lex, false, true)); // relative path
+ return TypeRef(TypeRef::TagPath(), Parse_Path(lex, false, PATH_GENERIC_TYPE)); // relative path
case TOK_DOUBLE_COLON:
// Path with generics
- //return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, true));
- throw ParseError::Todo("type ::");
+ return TypeRef(TypeRef::TagPath(), Parse_Path(lex, true, PATH_GENERIC_TYPE));
case TOK_AMP:
// Reference
tok = lex.getToken();
@@ -131,6 +169,8 @@ TypeRef Parse_Type(TokenStream& lex) } while( (tok = lex.getToken()).type() == TOK_COMMA );
GET_CHECK_TOK(tok, lex, TOK_PAREN_CLOSE);
return TypeRef(TypeRef::TagTuple(), types); }
+ case TOK_EXCLAM:
+ throw ParseError::Todo("noreturn type");
default:
throw ParseError::Unexpected(tok);
}
@@ -138,6 +178,8 @@ TypeRef Parse_Type(TokenStream& lex) AST::TypeParams Parse_TypeParams(TokenStream& lex)
{
+ TRACE_FUNCTION;
+
AST::TypeParams ret;
Token tok;
do {
@@ -183,9 +225,71 @@ AST::TypeParams Parse_TypeParams(TokenStream& lex) void Parse_TypeConds(TokenStream& lex, AST::TypeParams& params)
{
+ TRACE_FUNCTION;
throw ParseError::Todo("type param conditions (where)");
}
+/// Parse a function definition (after the 'fn')
+AST::Function Parse_FunctionDef(TokenStream& lex)
+{
+ Token tok;
+
+ // Name
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+
+ // Parameters
+ AST::TypeParams params;
+ if( GET_TOK(tok, lex) == TOK_LT )
+ {
+ params = Parse_TypeParams(lex);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+
+ //if(GET_TOK(tok, lex) == TOK_RWORD_WHERE)
+ //{
+ // Parse_TypeConds(lex, params);
+ // tok = lex.getToken();
+ //}
+ }
+ else {
+ lex.putback(tok);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_PAREN_OPEN);
+ ::std::vector<AST::StructItem> args;
+ if( GET_TOK(tok, lex) != TOK_PAREN_CLOSE )
+ {
+ // Argument list
+ lex.putback(tok);
+ do {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ GET_CHECK_TOK(tok, lex, TOK_COLON);
+ TypeRef type = Parse_Type(lex);
+ args.push_back( ::std::make_pair(name, type) );
+ tok = lex.getToken();
+ } while( tok.type() == TOK_COMMA );
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ }
+ else {
+ // Eat 'tok', negative comparison
+ }
+
+ TypeRef ret_type;
+ if( GET_TOK(tok, lex) == TOK_THINARROW )
+ {
+ // Return type
+ ret_type = Parse_Type(lex);
+ }
+ else
+ {
+ lex.putback(tok);
+ }
+
+ AST::Expr code = Parse_ExprBlock(lex);
+
+ return AST::Function(name, params, ret_type, args, code);
+}
+
AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex)
{
AST::Module mod;
@@ -210,7 +314,8 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) break;
case TOK_RWORD_USE:
- mod.add_alias( is_public, Parse_Path(lex, true, false) );
+ // TODO: Do manual path parsing here, as use has its own special set of quirks
+ mod.add_alias( is_public, Parse_Path(lex, true, PATH_GENERIC_NONE) );
GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
break;
@@ -246,56 +351,9 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) mod.add_global(is_public, is_mut, name, type, val);
break; }
- case TOK_RWORD_FN: {
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- tok = lex.getToken();
- AST::TypeParams params;
- if( tok.type() == TOK_LT )
- {
- params = Parse_TypeParams(lex);
- GET_CHECK_TOK(tok, lex, TOK_GT);
- tok = lex.getToken();
- if(tok.type() == TOK_RWORD_WHERE)
- {
- Parse_TypeConds(lex, params);
- tok = lex.getToken();
- }
- }
- CHECK_TOK(tok, TOK_PAREN_OPEN);
- tok = lex.getToken();
- ::std::vector<AST::StructItem> args;
- if( tok.type() != TOK_PAREN_CLOSE )
- {
- // Argument list
- lex.putback(tok);
- do {
- GET_CHECK_TOK(tok, lex, TOK_IDENT);
- ::std::string name = tok.str();
- GET_CHECK_TOK(tok, lex, TOK_COLON);
- TypeRef type = Parse_Type(lex);
- args.push_back( ::std::make_pair(name, type) );
- tok = lex.getToken();
- } while( tok.type() == TOK_COMMA );
- CHECK_TOK(tok, TOK_PAREN_CLOSE);
- }
-
- TypeRef ret_type;
- tok = lex.getToken();
- if( tok.type() == TOK_THINARROW )
- {
- // Return type
- ret_type = Parse_Type(lex);
- }
- else
- {
- lex.putback(tok);
- }
-
- AST::Expr code = Parse_ExprBlock(lex);
-
- mod.add_function(is_public, name, params, ret_type, args, code);
- break; }
+ case TOK_RWORD_FN:
+ mod.add_function(is_public, Parse_FunctionDef(lex));
+ break;
case TOK_RWORD_STRUCT: {
GET_CHECK_TOK(tok, lex, TOK_IDENT);
::std::string name = tok.str();
@@ -359,8 +417,63 @@ AST::Module Parse_ModRoot(bool is_own_file, Preproc& lex) break; }
case TOK_RWORD_ENUM:
throw ParseError::Todo("modroot enum");
- case TOK_RWORD_IMPL:
- throw ParseError::Todo("modroot impl");
+ case TOK_RWORD_IMPL: {
+ AST::TypeParams params;
+ // 1. (optional) type parameters
+ if( GET_TOK(tok, lex) == TOK_LT )
+ {
+ params = Parse_TypeParams(lex);
+ GET_CHECK_TOK(tok, lex, TOK_GT);
+ }
+ else {
+ lex.putback(tok);
+ }
+ // 2. Either a trait name (with type params), or the type to impl
+ // - Don't care which at this stage
+ TypeRef trait_type;
+ TypeRef impl_type = Parse_Type(lex);
+ if( GET_TOK(tok, lex) == TOK_RWORD_FOR )
+ {
+ // Implementing a trait for another type, get the target type
+ trait_type = impl_type;
+ impl_type = Parse_Type(lex);
+ }
+ else {
+ lex.putback(tok);
+ }
+ // Where clause
+ if( GET_TOK(tok, lex) == TOK_RWORD_WHERE )
+ {
+ Parse_TypeConds(lex, params);
+ }
+ else {
+ lex.putback(tok);
+ }
+ GET_CHECK_TOK(tok, lex, TOK_BRACE_OPEN);
+
+ AST::Impl impl(impl_type, trait_type);
+
+ // A sequence of method implementations
+ while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
+ {
+ bool is_public = false;
+ if(tok.type() == TOK_RWORD_PUB) {
+ is_public = true;
+ GET_TOK(tok, lex);
+ }
+ switch(tok.type())
+ {
+ case TOK_RWORD_FN:
+ impl.add_function(is_public, Parse_FunctionDef(lex));
+ break;
+
+ default:
+ throw ParseError::Unexpected(tok);
+ }
+ }
+
+ mod.add_impl(impl);
+ break; }
case TOK_RWORD_TRAIT:
throw ParseError::Todo("modroot trait");
@@ -9,6 +9,10 @@ class TypeRef {
public:
TypeRef() {}
+
+ struct TagUnit {}; // unit maps to a zero-length tuple, just easier to type
+ TypeRef(TagUnit) {}
+
struct TagPrimitive {};
TypeRef(TagPrimitive, enum eCoreType type) {}
struct TagTuple {};
|