diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 16 | ||||
-rw-r--r-- | src/ast/ast.hpp | 7 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 71 | ||||
-rw-r--r-- | src/parse/lex.cpp | 2 | ||||
-rw-r--r-- | src/parse/root.cpp | 133 |
6 files changed, 206 insertions, 25 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp index c2686787..a9336c31 100644 --- a/src/ast/ast.cpp +++ b/src/ast/ast.cpp @@ -49,7 +49,7 @@ SERIALISE_TYPE(Impl::, "AST_Impl", { })
Crate::Crate():
- m_root_module(*this, ""),
+ m_root_module(""),
m_load_std(true)
{
}
@@ -105,7 +105,7 @@ ExternCrate ExternCrate_std() // === Add modules ===
// - option
- Module option(crate.crate(), "option");
+ Module option("option");
option.add_enum(true, "Option", Enum(
{
TypeParam(false, "T"),
@@ -117,7 +117,7 @@ ExternCrate ExternCrate_std() ));
std_mod.add_submod(true, ::std::move(option));
// - result
- Module result(crate.crate(), "result");
+ Module result("result");
result.add_enum(true, "Result", Enum(
{
TypeParam(false, "R"),
@@ -130,7 +130,7 @@ ExternCrate ExternCrate_std() ));
std_mod.add_submod(true, ::std::move(result));
// - io
- Module io(crate.crate(), "io");
+ Module io("io");
io.add_typealias(true, "IoResult", TypeAlias(
{ TypeParam(false, "T") },
TypeRef( Path("std", {
@@ -141,18 +141,20 @@ ExternCrate ExternCrate_std() std_mod.add_submod(true, ::std::move(io));
// - iter
{
- Module iter(crate.crate(), "iter");
+ Module iter("iter");
+ #if 0
{
Trait iterator;
iterator.add_type("Item", TypeRef());
//iterator.add_function("next", Function({}, Function::CLASS_REFMETHOD, "Option<<Self as Iterator>::Item>", {}, Expr());
iter.add_trait(true, "Iterator", ::std::move(iterator));
}
+ #endif
std_mod.add_submod(true, ::std::move(iter));
}
// - prelude
- Module prelude(crate.crate(), "prelude");
+ Module prelude("prelude");
// Re-exports
#define USE(mod, name, ...) do{ Path p("std", {__VA_ARGS__}); mod.add_alias(true, ::std::move(p), name); } while(0)
USE(prelude, "Option", PathNode("option", {}), PathNode("Option",{}) );
@@ -178,8 +180,6 @@ SERIALISE_TYPE(Module::, "AST_Module", { void Module::add_ext_crate(::std::string ext_name, ::std::string int_name)
{
DEBUG("add_ext_crate(\"" << ext_name << "\" as " << int_name << ")");
- m_crate.load_extern_crate(ext_name);
-
m_extern_crates.push_back( Item< ::std::string>( ::std::move(int_name), ::std::move(ext_name), false ) );
}
void Module::iterate_functions(fcn_visitor_t *visitor, const Crate& crate)
diff --git a/src/ast/ast.hpp b/src/ast/ast.hpp index 77eb4fe3..f04c5ab0 100644 --- a/src/ast/ast.hpp +++ b/src/ast/ast.hpp @@ -267,7 +267,6 @@ class Module: typedef ::std::vector< Item<Enum> > itemlist_enum_t;
typedef ::std::vector< Item<Struct> > itemlist_struct_t;
- Crate& m_crate;
::std::string m_name;
::std::vector<MetaItem> m_attrs;
itemlist_fcn_t m_functions;
@@ -282,8 +281,7 @@ class Module: itemlist_struct_t m_structs;
::std::vector<Impl> m_impls;
public:
- Module(Crate& crate, ::std::string name):
- m_crate(crate),
+ Module(::std::string name):
m_name(name)
{
}
@@ -322,9 +320,6 @@ public: void iterate_functions(fcn_visitor_t* visitor, const Crate& crate);
- Crate& crate() { return m_crate; }
- const Crate& crate() const { return m_crate; }
-
const ::std::string& name() const { return m_name; }
::std::vector<MetaItem>& attrs() { return m_attrs; }
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index bba534a3..1ff0daab 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -402,6 +402,8 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod }
//throw ParseError::Todo("ResolvePaths_HandleModule - wildcard use on module");
break;
+ case AST::Path::ALIAS:
+ throw ParseError::Todo("ResolvePaths_HandleModule_Use - ALIAS");
case AST::Path::ENUM:
throw ParseError::Todo("ResolvePaths_HandleModule_Use - ENUM");
case AST::Path::ENUM_VAR:
diff --git a/src/main.cpp b/src/main.cpp index f35f93ce..55b6f9d4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include "parse/parseerror.hpp"
#include "ast/ast.hpp"
#include <serialiser_texttree.hpp>
+#include <cstring>
extern AST::Crate Parse_Crate(::std::string mainfile);
extern void ResolvePaths(AST::Crate& crate);
@@ -12,11 +13,71 @@ extern AST::Flat Convert_Flatten(const AST::Crate& crate); /// main!
int main(int argc, char *argv[])
{
+ const char *infile = NULL;
+ ::std::string outfile;
+ const char *crate_path = ".";
+ const char *emit_type = "c";
+ for( int i = 1; i < argc; i ++ )
+ {
+ const char* arg = argv[i];
+
+ if( arg[0] != '-' )
+ {
+ infile = arg;
+ }
+ else if( arg[1] != '-' )
+ {
+ arg ++; // eat '-'
+ for( ; *arg; arg ++ )
+ {
+ switch(*arg)
+ {
+ // "-o <file>" : Set output file
+ case 'o':
+ if( i == argc - 1 ) {
+ // TODO: BAIL!
+ return 1;
+ }
+ outfile = argv[++i];
+ break;
+ default:
+ return 1;
+ }
+ }
+ }
+ else
+ {
+ if( strcmp(arg, "--crate-path") == 0 ) {
+ if( i == argc - 1 ) {
+ // TODO: BAIL!
+ return 1;
+ }
+ crate_path = argv[++i];
+ }
+ else if( strcmp(arg, "--emit") == 0 ) {
+ if( i == argc - 1 ) {
+ // TODO: BAIL!
+ return 1;
+ }
+ emit_type = argv[++i];
+ }
+ else {
+ return 1;
+ }
+ }
+ }
+
+ if( outfile == "" )
+ {
+ outfile = infile;
+ outfile += ".o";
+ }
+
Serialiser_TextTree s_tt(::std::cout);
Serialiser& s = s_tt;
try
{
- AST::Crate crate = Parse_Crate("samples/1.rs");
+ AST::Crate crate = Parse_Crate(infile);
s << crate;
@@ -26,6 +87,13 @@ int main(int argc, char *argv[]) // Typecheck / type propagate module (type annotations of all values)
+ if( strcmp(emit_type, "ast") == 0 )
+ {
+ ::std::ofstream os(outfile);
+ Serialiser_TextTree os_tt(os);
+ ((Serialiser&)os_tt) << crate;
+ return 0;
+ }
// Flatten modules into "mangled" set
AST::Flat flat_crate = Convert_Flatten(crate);
@@ -35,6 +103,7 @@ int main(int argc, char *argv[]) catch(const ParseError::Base& e)
{
::std::cerr << "Parser Error: " << e.what() << ::std::endl;
+ return 2;
}
return 0;
}
diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index f893f26c..9655df0a 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -140,8 +140,8 @@ static const struct { TOKENT("static", TOK_RWORD_STATIC),
TOKENT("struct", TOK_RWORD_STRUCT),
TOKENT("super", TOK_RWORD_SUPER),
- TOKENT("true", TOK_RWORD_TRUE),
TOKENT("trait", TOK_RWORD_TRAIT),
+ TOKENT("true", TOK_RWORD_TRUE),
TOKENT("type", TOK_RWORD_TYPE),
TOKENT("typeof", TOK_RWORD_TYPEOF),
TOKENT("unsafe", TOK_RWORD_UNSAFE),
diff --git a/src/parse/root.cpp b/src/parse/root.cpp index 6be74e76..10eeacaf 100644 --- a/src/parse/root.cpp +++ b/src/parse/root.cpp @@ -328,8 +328,35 @@ AST::Function Parse_FunctionDef(TokenStream& lex) return AST::Function(params, fcn_class, ret_type, args, code);
}
+AST::TypeAlias Parse_TypeAlias(TokenStream& lex, const ::std::vector<AST::MetaItem> meta_items)
+{
+ TRACE_FUNCTION;
+
+ Token tok;
+
+ // Params
+ 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();
+ }
+
+ CHECK_TOK(tok, TOK_EQUAL);
+
+ // Type
+ TypeRef type = Parse_Type(lex);
+ GET_CHECK_TOK(tok, lex, TOK_SEMICOLON);
+
+ return AST::TypeAlias( ::std::move(params), ::std::move(type) );
+}
+
void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, const ::std::vector<AST::MetaItem> meta_items)
{
+ TRACE_FUNCTION;
+
Token tok;
GET_CHECK_TOK(tok, lex, TOK_IDENT);
@@ -393,6 +420,57 @@ void Parse_Struct(AST::Module& mod, TokenStream& lex, const bool is_public, cons }
}
+AST::Enum Parse_EnumDef(TokenStream& lex, const ::std::vector<AST::MetaItem> meta_items)
+{
+ TRACE_FUNCTION;
+
+ Token tok;
+
+ tok = lex.getToken();
+ // Type params supporting "where"
+ 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();
+ }
+ }
+
+ // Body
+ CHECK_TOK(tok, TOK_BRACE_OPEN);
+ ::std::vector<AST::StructItem> variants;
+ while( GET_TOK(tok, lex) != TOK_BRACE_CLOSE )
+ {
+ CHECK_TOK(tok, TOK_IDENT);
+ ::std::string name = tok.str();
+ ::std::vector<TypeRef> types;
+ if( GET_TOK(tok, lex) == TOK_PAREN_OPEN )
+ {
+ // Get type list
+ // TODO: Handle 'Variant()'?
+ do
+ {
+ types.push_back( Parse_Type(lex) );
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_PAREN_CLOSE);
+ GET_TOK(tok, lex);
+ }
+
+ variants.push_back( AST::StructItem(::std::move(name), TypeRef(TypeRef::TagTuple(), ::std::move(types))) );
+ if( tok.type() != TOK_COMMA )
+ break;
+ }
+ CHECK_TOK(tok, TOK_BRACE_CLOSE);
+
+
+ return AST::Enum( ::std::move(params), ::std::move(variants) );
+}
+
/// Parse a meta-item declaration (either #![ or #[)
AST::MetaItem Parse_MetaItem(TokenStream& lex)
{
@@ -486,6 +564,8 @@ void Parse_Use_Wildcard(const AST::Path& base_path, ::std::function<void(AST::Pa void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn)
{
+ TRACE_FUNCTION;
+
Token tok;
AST::Path path = AST::Path( AST::Path::TagAbsolute() );
@@ -515,8 +595,17 @@ void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn switch( tok.type() )
{
case TOK_BRACE_OPEN:
- throw ParseError::Todo("Parse_Use - multiples");
- break;
+ do {
+ if( GET_TOK(tok, lex) == TOK_RWORD_SELF ) {
+ fcn(path, path[path.size()-1].name());
+ }
+ else {
+ CHECK_TOK(tok, TOK_IDENT);
+ fcn(path + AST::PathNode(tok.str(), {}), tok.str());
+ }
+ } while( GET_TOK(tok, lex) == TOK_COMMA );
+ CHECK_TOK(tok, TOK_BRACE_CLOSE);
+ return;
case TOK_STAR:
Parse_Use_Wildcard(path, fcn);
// early return - can't have anything else after
@@ -545,12 +634,14 @@ void Parse_Use(Preproc& lex, ::std::function<void(AST::Path, ::std::string)> fcn fcn(path, name);
}
-void Parse_ModRoot(Preproc& lex, AST::Module& mod, const ::std::string& path)
+void Parse_ModRoot(Preproc& lex, AST::Crate& crate, AST::Module& mod, const ::std::string& path)
{
+ TRACE_FUNCTION;
+
const bool nested_module = (path.size() == 0); // 'mod name { code }', as opposed to 'mod name;'
Token tok;
- if( mod.crate().m_load_std )
+ if( crate.m_load_std )
{
// Import the prelude
AST::Path prelude_path = AST::Path(AST::Path::TagAbsolute());
@@ -658,19 +749,42 @@ void Parse_ModRoot(Preproc& lex, AST::Module& mod, const ::std::string& path) ::std::string name = tok.str();
mod.add_function(is_public, name, Parse_FunctionDef(lex));
break; }
+ case TOK_RWORD_TYPE: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ mod.add_typealias(is_public, name, Parse_TypeAlias(lex, meta_items));
+ break; }
case TOK_RWORD_STRUCT:
Parse_Struct(mod, lex, is_public, meta_items);
break;
- case TOK_RWORD_ENUM:
- throw ParseError::Todo("modroot enum");
+ case TOK_RWORD_ENUM: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ mod.add_enum(is_public, name, Parse_EnumDef(lex, meta_items));
+ break; }
case TOK_RWORD_IMPL:
mod.add_impl(Parse_Impl(lex));
break;
case TOK_RWORD_TRAIT:
throw ParseError::Todo("modroot trait");
- case TOK_RWORD_MOD:
- throw ParseError::Todo("sub-modules");
+ case TOK_RWORD_MOD: {
+ GET_CHECK_TOK(tok, lex, TOK_IDENT);
+ ::std::string name = tok.str();
+ AST::Module submod(name);
+ DEBUG("Sub module '"<<name<<"'");
+ switch( GET_TOK(tok, lex) )
+ {
+ case TOK_BRACE_OPEN:
+ Parse_ModRoot(lex, crate, submod, "");
+ break;
+ case TOK_SEMICOLON:
+ throw ParseError::Todo("sub-modules from other files");
+ default:
+ throw ParseError::Generic("Expected { or ; after module name");
+ }
+ mod.add_submod(is_public, ::std::move(submod));
+ break; }
default:
throw ParseError::Unexpected(tok);
@@ -710,6 +824,7 @@ AST::Crate Parse_Crate(::std::string mainfile) if( crate.m_load_std )
{
// Load the standard library (add 'extern crate std;')
+ crate.load_extern_crate("std");
rootmod.add_ext_crate("std", "std");
// Prelude imports are handled in Parse_ModRoot
}
@@ -717,7 +832,7 @@ AST::Crate Parse_Crate(::std::string mainfile) // Include the std if the 'no_std' attribute was absent
// - First need to load the std macros, then can import the prelude
- Parse_ModRoot(lex, rootmod, mainfile);
+ Parse_ModRoot(lex, crate, rootmod, mainfile);
return crate;
}
|