summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/ast.cpp15
-rw-r--r--src/ast/path.cpp34
-rw-r--r--src/ast/path.hpp162
-rw-r--r--src/convert/ast_iterate.cpp16
-rw-r--r--src/convert/render.cpp18
-rw-r--r--src/convert/resolve.cpp14
-rw-r--r--src/convert/typecheck_bounds.cpp5
-rw-r--r--src/convert/typecheck_expr.cpp30
-rw-r--r--src/convert/typecheck_params.cpp26
-rw-r--r--src/main.cpp155
10 files changed, 262 insertions, 213 deletions
diff --git a/src/ast/ast.cpp b/src/ast/ast.cpp
index 11632996..efd1e830 100644
--- a/src/ast/ast.cpp
+++ b/src/ast/ast.cpp
@@ -500,7 +500,8 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves
//if( &imp.data == this )
// continue ;
//
- if( !imp.data.is_bound() )
+ const auto& binding = imp.data.binding();
+ if( !binding.is_bound() )
{
// not yet bound, so run resolution (recursion)
DEBUG("Recursively resolving pub wildcard use " << imp.data);
@@ -508,13 +509,13 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves
throw ParseError::Todo("Path::resolve() wildcard re-export call resolve");
}
- switch(imp.data.binding_type())
+ switch(binding.type())
{
- case AST::Path::UNBOUND:
+ case AST::PathBinding::UNBOUND:
throw ParseError::BugCheck("Wildcard import path not bound");
// - If it's a module, recurse
- case AST::Path::MODULE: {
- auto rv = imp.data.bound_module().find_item(needle);
+ case AST::PathBinding::MODULE: {
+ auto rv = binding.bound_module().find_item(needle);
if( rv.type() != Module::ItemRef::ITEM_none ) {
// Don't return RV, return the import (so caller can rewrite path if need be)
return ItemRef(imp);
@@ -522,8 +523,8 @@ Module::ItemRef Module::find_item(const ::std::string& needle, bool allow_leaves
}
break; }
// - If it's an enum, search for this name and then pass to resolve
- case AST::Path::ENUM: {
- auto& vars = imp.data.bound_enum().variants();
+ case AST::PathBinding::ENUM: {
+ auto& vars = binding.bound_enum().variants();
// Damnit C++ "let it = vars.find(|a| a.name == needle);"
auto it = ::std::find_if(vars.begin(), vars.end(),
[&needle](const EnumVariant& ev) { return ev.m_name == needle; });
diff --git a/src/ast/path.cpp b/src/ast/path.cpp
index 9548730e..2cfd6b98 100644
--- a/src/ast/path.cpp
+++ b/src/ast/path.cpp
@@ -151,8 +151,7 @@ void Path::resolve(const Crate& root_crate)
// Make a copy of the path, replace params with it, then replace *this?
// - Maybe leave that up to other code?
if( is_last ) {
- m_binding_type = ALIAS;
- m_binding.alias_ = &ta;
+ m_binding = PathBinding(&ta);
goto ret;
}
else {
@@ -165,8 +164,7 @@ void Path::resolve(const Crate& root_crate)
const auto& fn = item.unwrap_Function();
DEBUG("Found function");
if( is_last ) {
- m_binding_type = FUNCTION;
- m_binding.func_ = &fn;
+ m_binding = PathBinding(&fn);
goto ret;
}
else {
@@ -179,13 +177,11 @@ void Path::resolve(const Crate& root_crate)
const auto& t = item.unwrap_Trait();
DEBUG("Found trait");
if( is_last ) {
- m_binding_type = TRAIT;
- m_binding.trait_ = &t;
+ m_binding = PathBinding(&t);
goto ret;
}
else if( is_sec_last ) {
- m_binding_type = TRAIT_METHOD;
- m_binding.trait_ = &t;
+ m_binding = PathBinding(PathBinding::TagItem(), &t);
goto ret;
}
else {
@@ -282,7 +278,7 @@ void Path::resolve(const Crate& root_crate)
}
// We only reach here if the path points to a module
- bind_module(*mod);
+ m_binding = PathBinding(mod);
ret:
if( slice_from > 0 )
{
@@ -291,16 +287,10 @@ ret:
}
return ;
}
-void Path::bind_module(const Module& mod)
-{
- m_binding_type = MODULE;
- m_binding.module_ = &mod;
-}
void Path::bind_enum(const Enum& ent, const ::std::vector<TypeRef>& args)
{
DEBUG("Bound to enum");
- m_binding_type = ENUM;
- m_binding.enum_ = &ent;
+ m_binding = PathBinding(&ent);
//if( args.size() > 0 )
//{
// if( args.size() != ent.params().size() )
@@ -328,8 +318,7 @@ void Path::bind_enum_var(const Enum& ent, const ::std::string& name, const ::std
//}
DEBUG("Bound to enum variant '" << name << "' (#" << idx << ")");
- m_binding_type = ENUM_VAR;
- m_binding.enumvar = {&ent, idx};
+ m_binding = PathBinding(&ent, idx);
}
void Path::bind_struct(const Struct& ent, const ::std::vector<TypeRef>& args)
{
@@ -343,19 +332,16 @@ void Path::bind_struct(const Struct& ent, const ::std::vector<TypeRef>& args)
//}
DEBUG("Bound to struct");
- m_binding_type = STRUCT;
- m_binding.struct_ = &ent;
+ m_binding = PathBinding(&ent);
}
void Path::bind_struct_member(const Struct& ent, const ::std::vector<TypeRef>& args, const PathNode& member_node)
{
DEBUG("Binding to struct item. This needs to be deferred");
- m_binding_type = STRUCT_METHOD;
- m_binding.struct_ = &ent;
+ m_binding = PathBinding(PathBinding::TagItem(), &ent);
}
void Path::bind_static(const Static& ent)
{
- m_binding_type = STATIC;
- m_binding.static_ = &ent;
+ m_binding = PathBinding(&ent);
}
diff --git a/src/ast/path.hpp b/src/ast/path.hpp
index 03aeab23..b3af8c52 100644
--- a/src/ast/path.hpp
+++ b/src/ast/path.hpp
@@ -25,6 +25,102 @@ class Trait;
class Static;
class Function;
+//TAGGED_ENUM(Binding, Unbound,
+// (BndModule, (const Module* module_; ) ),
+// (BndEnum, (const Enum* enum_; ) ),
+// (BndStruct, (const Struct* struct_; ) ),
+// (BndTrait, (const Trait* trait_; ) ),
+// (BndStatic, (const Static* static_; ) ),
+// (BndFunction, (const Function* func_; ) ),
+// (BndEnumVar, (const Enum* enum_; unsigned int idx; ) ),
+// (BndTypeAlias, (const TypeAlias* alias_; ) ),
+// (BndStructMethod, (const Struct* struct_; ::std::string name; ) ),
+// (BndTraitMethod, (const Trait* struct_; ::std::string name; ) )
+// );
+class PathBinding
+{
+public:
+ enum BindingType {
+ UNBOUND,
+ MODULE,
+ ALIAS,
+ ENUM,
+ STRUCT,
+ TRAIT,
+
+ STRUCT_METHOD,
+ TRAIT_METHOD,
+ ENUM_VAR,
+ FUNCTION,
+ STATIC,
+ };
+ struct EnumVar {
+ const Enum* enum_;
+ unsigned int idx;
+ };
+private:
+ BindingType m_binding_type = UNBOUND;
+ union {
+ const Module* module_;
+ const Enum* enum_;
+ const Struct* struct_;
+ struct {
+ const Struct* struct_;
+ unsigned int idx;
+ } structitem;
+ const Trait* trait_;
+ const Static* static_;
+ const Function* func_;
+ EnumVar enumvar_;
+ const TypeAlias* alias_;
+ } m_binding;
+
+public:
+ PathBinding(): m_binding_type(UNBOUND) {}
+
+ bool is_bound() const { return m_binding_type != UNBOUND; }
+ BindingType type() const { return m_binding_type; }
+ #define _(t, n, v)\
+ PathBinding(const t* i): m_binding_type(v) { m_binding.n##_ = i; } \
+ const t& bound_##n() const { assert(m_binding_type == v); return *m_binding.n##_; }
+ _(Module, module, MODULE)
+ _(Trait, trait, TRAIT)
+ _(Struct, struct, STRUCT)
+ _(Enum, enum, ENUM)
+ _(Function, func, FUNCTION)
+ _(Static, static, STATIC)
+ _(TypeAlias, alias, ALIAS)
+ //_(EnumVar, enumvar, ENUM_VAR)
+ #undef _
+ PathBinding(const Enum* enm, unsigned int i):
+ m_binding_type(ENUM_VAR)
+ {
+ m_binding.enumvar_ = {enm, i};
+ }
+ const EnumVar& bound_enumvar() const { assert(m_binding_type == ENUM_VAR); return m_binding.enumvar_; }
+
+ struct TagItem {};
+ PathBinding(TagItem, const Trait* t): m_binding_type(TRAIT_METHOD) { m_binding.trait_ = t; }
+ PathBinding(TagItem, const Struct* i): m_binding_type(STRUCT_METHOD) { m_binding.struct_ = i; }
+
+ friend ::std::ostream& operator<<(::std::ostream& os, const PathBinding& x) {
+ switch(x.m_binding_type)
+ {
+ case UNBOUND: os << "UNBOUND"; break;
+ case MODULE: os << "Module"; break;
+ case TRAIT: os << "Trait"; break;
+ case STRUCT: os << "Struct"; break;
+ case ENUM: os << "Enum"; break;
+ case FUNCTION: os << "Function";break;
+ case STATIC: os << "Static"; break;
+ case ALIAS: os << "Alias"; break;
+ case STRUCT_METHOD: os << "StructMethod"; break;
+ case TRAIT_METHOD: os << "TraitMethod"; break;
+ case ENUM_VAR: os << "EnumVar(" << x.m_binding.enumvar_.idx << ")"; break;
+ }
+ return os;
+ }
+};
class PathNode:
public ::Serialisable
@@ -48,33 +144,6 @@ public:
class Path:
public ::Serialisable
{
-public:
- enum BindingType {
- UNBOUND,
- MODULE,
- ALIAS,
- ENUM,
- STRUCT,
- TRAIT,
-
- STRUCT_METHOD,
- TRAIT_METHOD,
- ENUM_VAR,
- FUNCTION,
- STATIC,
- };
- //TAGGED_ENUM(Binding, Unbound,
- // (BndModule, (const Module* module_; ) ),
- // (BndEnum, (const Enum* enum_; ) ),
- // (BndStruct, (const Struct* struct_; ) ),
- // (BndTrait, (const Trait* trait_; ) ),
- // (BndStatic, (const Static* static_; ) ),
- // (BndFunction, (const Function* func_; ) ),
- // (BndEnumVar, (const Enum* enum_; unsigned int idx; ) ),
- // (BndTypeAlias, (const TypeAlias* alias_; ) ),
- // (BndStructMethod, (const Struct* struct_; ::std::string name; ) ),
- // (BndTraitMethod, (const Trait* struct_; ::std::string name; ) )
- // );
private:
enum Class {
RELATIVE,
@@ -95,24 +164,7 @@ private:
::std::vector<TypeRef> m_ufcs;
::std::vector<PathNode> m_nodes;
- BindingType m_binding_type = UNBOUND;
- union {
- const Module* module_;
- const Enum* enum_;
- const Struct* struct_;
- struct {
- const Struct* struct_;
- unsigned int idx;
- } structitem;
- const Trait* trait_;
- const Static* static_;
- const Function* func_;
- struct {
- const Enum* enum_;
- unsigned int idx;
- } enumvar;
- const TypeAlias* alias_;
- } m_binding;
+ PathBinding m_binding;
public:
Path():
m_class(RELATIVE)
@@ -196,25 +248,7 @@ public:
bool is_relative() const { return m_class == RELATIVE; }
size_t size() const { return m_nodes.size(); }
- bool is_bound() const { return m_binding_type != UNBOUND; }
- BindingType binding_type() const { return m_binding_type; }
- #define _(t, n, v) const t& bound_##n() const { assert(m_binding_type == v); return *m_binding.n##_; }
- _(Module, module, MODULE)
- _(Trait, trait, TRAIT)
- _(Struct, struct, STRUCT)
- //_(Enum, enum, ENUM)
- _(Function, func, FUNCTION)
- _(Static, static, STATIC)
- _(TypeAlias, alias, ALIAS)
- #undef _
- const Enum& bound_enum() const {
- assert(m_binding_type == ENUM || m_binding_type == ENUM_VAR); // Kinda evil, given that it has its own union entry
- return *m_binding.enum_;
- }
- const unsigned int bound_idx() const {
- assert(m_binding_type == ENUM_VAR);
- return m_binding.enumvar.idx;
- }
+ const PathBinding& binding() const { return m_binding; }
::std::vector<PathNode>& nodes() { return m_nodes; }
const ::std::vector<PathNode>& nodes() const { return m_nodes; }
diff --git a/src/convert/ast_iterate.cpp b/src/convert/ast_iterate.cpp
index a38bcb9c..405d55df 100644
--- a/src/convert/ast_iterate.cpp
+++ b/src/convert/ast_iterate.cpp
@@ -150,20 +150,22 @@ void CASTIterator::handle_pattern(AST::Pattern& pat, const TypeRef& type_hint)
{
auto& hint_path = type_hint.path();
auto& pat_path = v.path;
+ const auto& hint_binding = hint_path.binding();
+ const auto& pat_binding = pat_path.binding();
DEBUG("Pat: " << pat_path << ", Type: " << type_hint.path());
- switch( hint_path.binding_type() )
+ switch( hint_binding.type() )
{
- case AST::Path::UNBOUND:
+ case AST::PathBinding::UNBOUND:
throw ::std::runtime_error("Unbound path in pattern");
- case AST::Path::ENUM: {
+ case AST::PathBinding::ENUM: {
// The pattern's path must refer to a variant of the hint path
// - Actual type params are checked by the 'handle_pattern_enum' code
- if( pat_path.binding_type() != AST::Path::ENUM_VAR )
+ if( pat_binding.type() != AST::PathBinding::ENUM_VAR )
throw ::std::runtime_error(FMT("Paths in pattern are invalid"));
- if( &pat_path.bound_enum() != &hint_path.bound_enum() )
+ if( pat_binding.bound_enumvar().enum_ != &hint_binding.bound_enum() )
throw ::std::runtime_error(FMT("Paths in pattern are invalid"));
- auto& enm = pat_path.bound_enum();
- auto idx = pat_path.bound_idx();
+ const auto& enm = *pat_binding.bound_enumvar().enum_;
+ auto idx = pat_binding.bound_enumvar().idx;
auto& var = enm.variants().at(idx);
handle_pattern_enum(pat_path[-2].args(), hint_path[-1].args(), enm.params(), var, v.sub_patterns);
break; }
diff --git a/src/convert/render.cpp b/src/convert/render.cpp
index ce64e600..5c388d07 100644
--- a/src/convert/render.cpp
+++ b/src/convert/render.cpp
@@ -42,15 +42,15 @@ void Render_Crate(::std::ostream& os, const AST::Flat& crate)
const auto& fcn = item.second;
Render_Type(os, fcn.rettype(), nullptr);
os << " " << name << "(";
- bool is_first = true;
- for(const auto& f : fcn.args())
- {
- if( !is_first )
- os << ", ";
- is_first = false;
- // TODO: handle pattern
- //Render_Type(os, f.second, f.first.c_str());
- }
+ //bool is_first = true;
+ //for(const auto& f : fcn.args())
+ //{
+ // if( !is_first )
+ // os << ", ";
+ // is_first = false;
+ // // TODO: handle pattern
+ // //Render_Type(os, f.second, f.first.c_str());
+ //}
os << ")\n{\n";
// Dump expression AST
os << "}\n";
diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp
index d0edc165..2e97b11b 100644
--- a/src/convert/resolve.cpp
+++ b/src/convert/resolve.cpp
@@ -358,7 +358,7 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode)
INDENT();
// Already absolute, our job is done
// - However, if the path isn't bound, bind it
- if( !path.is_bound() ) {
+ if( !path.binding().is_bound() ) {
path.resolve(m_crate);
}
UNINDENT();
@@ -417,7 +417,7 @@ void CPathResolver::handle_path(AST::Path& path, CASTIterator::PathMode mode)
local_path.resolve(m_crate);
DEBUG("'super' path is relative to " << local_path);
path.nodes().erase( path.nodes().begin() ); // delete the 'super' node
- const AST::Module& mod = local_path.bound_module();
+ const AST::Module& mod = local_path.binding().bound_module();
if( lookup_path_in_module(m_crate, mod, local_path, path) )
return ;
// this should always be an error, as 'super' paths are never MaybeBind
@@ -554,13 +554,13 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod
// If wildcard, make sure it's sane
if( imp.name == "" )
{
- switch(imp.data.binding_type())
+ switch(imp.data.binding().type())
{
- case AST::Path::UNBOUND:
+ case AST::PathBinding::UNBOUND:
throw ParseError::BugCheck("path unbound after calling .resolve()");
- case AST::Path::MODULE:
+ case AST::PathBinding::MODULE:
break;
- case AST::Path::ENUM:
+ case AST::PathBinding::ENUM:
break;
default:
@@ -571,7 +571,7 @@ void ResolvePaths_HandleModule_Use(const AST::Crate& crate, const AST::Path& mod
for( auto& new_imp : new_imports )
{
- if( not new_imp.is_bound() ) {
+ if( not new_imp.binding().is_bound() ) {
new_imp.resolve(crate);
}
mod.add_alias(false, new_imp, new_imp[new_imp.size()-1].name());
diff --git a/src/convert/typecheck_bounds.cpp b/src/convert/typecheck_bounds.cpp
index 3f3e6b8d..4112bf27 100644
--- a/src/convert/typecheck_bounds.cpp
+++ b/src/convert/typecheck_bounds.cpp
@@ -25,11 +25,12 @@ void CGenericBoundChecker::handle_params(AST::TypeParams& params)
if( bound.is_trait() )
{
auto& trait = bound.bound();
+ assert(trait.binding().is_bound());
DEBUG("trait = " << trait);
- if( trait.binding_type() != AST::Path::TRAIT )
+ if( trait.binding().type() != AST::PathBinding::TRAIT )
{
//throw CompileError::BoundNotTrait( bound.lex_scope(), bound.param(), trait );
- throw ::std::runtime_error(FMT("TODO - Bound " << trait << " not a trait"));
+ throw ::std::runtime_error(FMT("TODO - Bound " << trait << " not a trait : " << trait.binding()));
}
else {
DEBUG("Bound is a trait, good");
diff --git a/src/convert/typecheck_expr.cpp b/src/convert/typecheck_expr.cpp
index a6a69186..8cb290c3 100644
--- a/src/convert/typecheck_expr.cpp
+++ b/src/convert/typecheck_expr.cpp
@@ -298,14 +298,14 @@ void CTC_NodeVisitor::visit(AST::ExprNode_NamedValue& node)
if( p.is_absolute() )
{
// grab bound item
- switch(p.binding_type())
+ switch(p.binding().type())
{
- case AST::Path::STATIC:
- node.get_res_type() = p.bound_static().type();
+ case AST::PathBinding::STATIC:
+ node.get_res_type() = p.binding().bound_static().type();
break;
- case AST::Path::ENUM_VAR: {
- const AST::Enum& enm = p.bound_enum();
- auto idx = p.bound_idx();
+ case AST::PathBinding::ENUM_VAR: {
+ const AST::Enum& enm = *p.binding().bound_enumvar().enum_;
+ auto idx = p.binding().bound_enumvar().idx;
// Enum variant:
// - Check that this variant takes no arguments
if( enm.variants()[idx].m_sub_types.size() > 0 )
@@ -413,11 +413,11 @@ void CTC_NodeVisitor::visit(AST::ExprNode_Field& node)
// TODO Move this logic to types.cpp?
const AST::Path& p = tr->path();
- switch( p.binding_type() )
+ switch( p.binding().type() )
{
- case AST::Path::STRUCT: {
+ case AST::PathBinding::STRUCT: {
const AST::PathNode& lastnode = p.nodes().back();
- AST::Struct& s = const_cast<AST::Struct&>( p.bound_struct() );
+ AST::Struct& s = const_cast<AST::Struct&>( p.binding().bound_struct() );
node.get_res_type().merge_with( s.get_field_type(node.m_name.c_str(), lastnode.args()) );
break; }
default:
@@ -483,7 +483,7 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallMethod& node)
for( const auto& t : ltype.traits() )
{
DEBUG("- Trait " << t.path());
- AST::Trait& trait = const_cast<AST::Trait&>( t.path().bound_trait() );
+ AST::Trait& trait = const_cast<AST::Trait&>( t.path().binding().bound_trait() );
// - Find method on one of them
for( auto& m : trait.functions() )
{
@@ -572,9 +572,9 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
argtypes.push_back( arg->get_res_type() );
}
- if(node.m_path.binding_type() == AST::Path::FUNCTION)
+ if(node.m_path.binding().type() == AST::PathBinding::FUNCTION)
{
- const AST::Function& fcn = node.m_path.bound_func();
+ const AST::Function& fcn = node.m_path.binding().bound_func();
if( fcn.params().n_params() > 0 )
{
@@ -584,10 +584,10 @@ void CTC_NodeVisitor::visit(AST::ExprNode_CallPath& node)
DEBUG("ExprNode_CallPath - rt = " << fcn.rettype());
node.get_res_type().merge_with( fcn.rettype() );
}
- else if(node.m_path.binding_type() == AST::Path::ENUM_VAR)
+ else if(node.m_path.binding().type() == AST::PathBinding::ENUM_VAR)
{
- const AST::Enum& enm = node.m_path.bound_enum();
- const unsigned int idx = node.m_path.bound_idx();
+ const AST::Enum& enm = *node.m_path.binding().bound_enumvar().enum_;
+ const unsigned int idx = node.m_path.binding().bound_enumvar().idx;
auto& path_node_enum = node.m_path[node.m_path.size()-2];
m_tc.check_enum_variant(path_node_enum.args(), argtypes, enm.params(), enm.variants().at(idx));
diff --git a/src/convert/typecheck_params.cpp b/src/convert/typecheck_params.cpp
index b028c55f..3b0a5a93 100644
--- a/src/convert/typecheck_params.cpp
+++ b/src/convert/typecheck_params.cpp
@@ -181,27 +181,27 @@ void CGenericParamChecker::handle_path(AST::Path& path, CASTIterator::PathMode p
DEBUG("path = " << path);
AST::PathNode& last_node = path[path.size()-1];
const AST::TypeParams* params = nullptr;
- switch(path.binding_type())
+ switch(path.binding().type())
{
- case AST::Path::UNBOUND:
+ case AST::PathBinding::UNBOUND:
throw ::std::runtime_error("CGenericParamChecker::handle_path - Unbound path");
- case AST::Path::MODULE:
+ case AST::PathBinding::MODULE:
DEBUG("WTF - Module path, isn't this invalid at this stage?");
break;
- case AST::Path::TRAIT:
- params = &path.bound_trait().params();
+ case AST::PathBinding::TRAIT:
+ params = &path.binding().bound_trait().params();
if(0)
- case AST::Path::STRUCT:
- params = &path.bound_struct().params();
+ case AST::PathBinding::STRUCT:
+ params = &path.binding().bound_struct().params();
if(0)
- case AST::Path::ENUM:
- params = &path.bound_enum().params();
+ case AST::PathBinding::ENUM:
+ params = &path.binding().bound_enum().params();
if(0)
- case AST::Path::ALIAS:
- params = &path.bound_alias().params();
+ case AST::PathBinding::ALIAS:
+ params = &path.binding().bound_alias().params();
if(0)
- case AST::Path::FUNCTION:
- params = &path.bound_func().params();
+ case AST::PathBinding::FUNCTION:
+ params = &path.binding().bound_func().params();
try {
check_generic_params(*params, last_node.args(), (m_within_expr > 0));
diff --git a/src/main.cpp b/src/main.cpp
index 85224156..e0188012 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -28,82 +28,38 @@ bool debug_enabled()
return ::std::cout << g_cur_phase << "- " << RepeatLitStr { " ", indent } << function << ": ";
}
+struct ProgramParams
+{
+ static const unsigned int EMIT_C = 0x1;
+ static const unsigned int EMIT_AST = 0x2;
+
+ const char *infile = NULL;
+ ::std::string outfile;
+ const char *crate_path = ".";
+ unsigned emit_flags = EMIT_C;
+
+ ProgramParams(int argc, char *argv[]);
+};
+
/// main!
int main(int argc, char *argv[])
{
AST_InitProvidedModule();
- // Hacky command-line parsing
- 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;
- }
- }
- }
+
+ ProgramParams params(argc, argv);
- if( outfile == "" )
- {
- outfile = infile;
- outfile += ".o";
- }
try
{
g_cur_phase = "Parse";
- AST::Crate crate = Parse_Crate(infile);
+ AST::Crate crate = Parse_Crate(params.infile);
g_cur_phase = "PostParse";
crate.post_parse();
//s << crate;
g_cur_phase = "Temp output";
- Dump_Rust( FMT(outfile << ".rs").c_str(), crate );
+ Dump_Rust( FMT(params.outfile << ".rs").c_str(), crate );
// Resolve names to be absolute names (include references to the relevant struct/global/function)
g_cur_phase = "Resolve";
@@ -113,7 +69,7 @@ int main(int argc, char *argv[])
// Typecheck / type propagate module (type annotations of all values)
// - Check all generic conditions (ensure referenced trait is valid)
// > Also mark parameter with applicable traits
- #if 0
+ #if 1
g_cur_phase = "TypecheckBounds";
Typecheck_GenericBounds(crate);
// - Check all generic parameters match required conditions
@@ -127,11 +83,11 @@ int main(int argc, char *argv[])
#endif
g_cur_phase = "Output";
- Dump_Rust( FMT(outfile << ".rs").c_str(), crate );
+ Dump_Rust( FMT(params.outfile << ".rs").c_str(), crate );
- if( strcmp(emit_type, "ast") == 0 )
+ if( params.emit_flags == ProgramParams::EMIT_AST )
{
- ::std::ofstream os(outfile);
+ ::std::ofstream os(params.outfile);
Serialiser_TextTree os_tt(os);
((Serialiser&)os_tt) << crate;
return 0;
@@ -155,3 +111,72 @@ int main(int argc, char *argv[])
}
return 0;
}
+
+ProgramParams::ProgramParams(int argc, char *argv[])
+{
+ // Hacky command-line parsing
+ for( int i = 1; i < argc; i ++ )
+ {
+ const char* arg = argv[i];
+
+ if( arg[0] != '-' )
+ {
+ this->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!
+ exit(1);
+ }
+ this->outfile = argv[++i];
+ break;
+ default:
+ exit(1);
+ }
+ }
+ }
+ else
+ {
+ if( strcmp(arg, "--crate-path") == 0 ) {
+ if( i == argc - 1 ) {
+ // TODO: BAIL!
+ exit(1);
+ }
+ this->crate_path = argv[++i];
+ }
+ else if( strcmp(arg, "--emit") == 0 ) {
+ if( i == argc - 1 ) {
+ // TODO: BAIL!
+ exit(1);
+ }
+
+ arg = argv[++i];
+ if( strcmp(arg, "ast") == 0 )
+ this->emit_flags = EMIT_AST;
+ else if( strcmp(arg, "c") == 0 )
+ this->emit_flags = EMIT_C;
+ else {
+ ::std::cerr << "Unknown argument to --emit : '" << arg << "'" << ::std::endl;
+ exit(1);
+ }
+ }
+ else {
+ exit(1);
+ }
+ }
+ }
+
+ if( this->outfile == "" )
+ {
+ this->outfile = (::std::string)this->infile + ".o";
+ }
+}
+