diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ast/ast.cpp | 15 | ||||
-rw-r--r-- | src/ast/path.cpp | 34 | ||||
-rw-r--r-- | src/ast/path.hpp | 162 | ||||
-rw-r--r-- | src/convert/ast_iterate.cpp | 16 | ||||
-rw-r--r-- | src/convert/render.cpp | 18 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 14 | ||||
-rw-r--r-- | src/convert/typecheck_bounds.cpp | 5 | ||||
-rw-r--r-- | src/convert/typecheck_expr.cpp | 30 | ||||
-rw-r--r-- | src/convert/typecheck_params.cpp | 26 | ||||
-rw-r--r-- | src/main.cpp | 155 |
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";
+ }
+}
+
|