diff options
-rw-r--r-- | src/ast/path.cpp | 101 | ||||
-rw-r--r-- | src/ast/path.hpp | 5 | ||||
-rw-r--r-- | src/convert/resolve.cpp | 54 | ||||
-rw-r--r-- | src/coretypes.hpp | 1 | ||||
-rw-r--r-- | src/dump_as_rust.cpp | 43 | ||||
-rw-r--r-- | src/include/cpp_unpack.h | 33 | ||||
-rw-r--r-- | src/include/span.hpp | 1 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 6 | ||||
-rw-r--r-- | src/parse/lex.cpp | 3 | ||||
-rw-r--r-- | src/parse/types.cpp | 47 | ||||
-rw-r--r-- | src/types.cpp | 35 |
11 files changed, 199 insertions, 130 deletions
diff --git a/src/ast/path.cpp b/src/ast/path.cpp index df5109c9..c2250999 100644 --- a/src/ast/path.cpp +++ b/src/ast/path.cpp @@ -55,14 +55,20 @@ Ordering PathNode::ord(const PathNode& x) const if(rv != OrdEqual) return rv; return OrdEqual; } -::std::ostream& operator<<(::std::ostream& os, const PathNode& pn) { - os << pn.m_name; - if( pn.m_params.size() ) +void PathNode::print_pretty(::std::ostream& os, bool is_type_context) const +{ + os << m_name; + if( m_params.size() ) { - os << "::<"; - os << pn.m_params; + if( is_type_context ) + os << "::"; + os << "<"; + os << m_params; os << ">"; } +} +::std::ostream& operator<<(::std::ostream& os, const PathNode& pn) { + pn.print_pretty(os, false); return os; } SERIALISE_TYPE(PathNode::, "PathNode", { @@ -424,98 +430,75 @@ Ordering Path::ord(const Path& x) const return OrdEqual; } -void Path::print_pretty(::std::ostream& os) const +void Path::print_pretty(::std::ostream& os, bool is_type_context) const { TU_MATCH(Path::Class, (m_class), (ent), - (Invalid, os << "/* inv */"; ), - (Local, os << ent.name;), - (Relative, - for(const auto& n : ent.nodes) os << "::" << n; - ), - (Self, - os << "self"; - for(const auto& n : ent.nodes) os << "::" << n; - ), - (Super, - os << "super"; - for(const auto& n : ent.nodes) os << "::" << n; - ), - (Absolute, - if( m_crate != "" ) - os << "::\"" << m_crate << "\""; - for(const auto& n : ent.nodes) - os << "::" << n; - ), - (UFCS, - throw ParseError::Todo("Path::print_pretty - UFCS"); - ) - ) -} - -::std::ostream& operator<<(::std::ostream& os, const Path& path) -{ - //if( path.m_nodes.size() == 0 && path.m_class == Path::RELATIVE ) - //{ - // os << "/* null path */"; - // return os; - //} - #if PRETTY_PATH_PRINT - TU_MATCH(Path::Class, (path.m_class), (ent), (Invalid, os << "/*inv*/"; ), (Local, - os << "/*var*/" << ent.name; + // Only print comment if there's no binding + if( m_binding.is_Unbound() ) + os << "/*var*/"; + else + assert( m_binding.is_Variable() ); + os << ent.name; ), (Relative, for(const auto& n : ent.nodes) { - #if PRETTY_PATH_PRINT if( &n != &ent.nodes[0] ) { os << "::"; } - #endif - os << n; + n.print_pretty(os, is_type_context); } ), (Self, os << "self"; for(const auto& n : ent.nodes) { - #if PRETTY_PATH_PRINT os << "::"; - #endif - os << n; + n.print_pretty(os, is_type_context); } ), (Super, os << "super"; for(const auto& n : ent.nodes) { - #if PRETTY_PATH_PRINT os << "::"; - #endif - os << n; + n.print_pretty(os, is_type_context); } ), (Absolute, - if( path.m_crate != "" ) - os << "::\""<<path.m_crate<<"\""; + if( m_crate != "" ) + os << "::\"" << m_crate << "\""; for(const auto& n : ent.nodes) { - #if PRETTY_PATH_PRINT os << "::"; - #endif - os << n; + n.print_pretty(os, is_type_context); } ), (UFCS, - os << "/*ufcs*/<" << *ent.type << " as " << *ent.trait << ">"; - for(const auto& n : ent.nodes) - os << "::" << n; + //os << "/*ufcs*/"; + if( ! ent.trait->m_data.is_None() ) { + os << "<" << *ent.type << " as " << *ent.trait << ">"; + } + else { + os << "<" << *ent.type << ">"; + } + for(const auto& n : ent.nodes) { + os << "::"; + n.print_pretty(os, is_type_context); + } ) ) - os << "/*" << path.m_binding << "*/"; + os << "/*" << m_binding << "*/"; +} + +::std::ostream& operator<<(::std::ostream& os, const Path& path) +{ + #if PRETTY_PATH_PRINT + path.print_pretty(os, false); #else switch(path.m_class) { diff --git a/src/ast/path.hpp b/src/ast/path.hpp index 1d627a87..cbe009f9 100644 --- a/src/ast/path.hpp +++ b/src/ast/path.hpp @@ -90,8 +90,9 @@ public: const ::std::vector<TypeRef>& args() const; Ordering ord(const PathNode& x) const; + void print_pretty(::std::ostream& os, bool is_type_context) const; + bool operator==(const PathNode& x) const { return ord(x) == OrdEqual; } - void print_pretty(::std::ostream& os) const; friend ::std::ostream& operator<<(::std::ostream& os, const PathNode& pn); SERIALISABLE_PROTOTYPES(); @@ -317,7 +318,7 @@ public: bool operator<(const Path& x) const { return ord(x) != OrdLess; } SERIALISABLE_PROTOTYPES(); - void print_pretty(::std::ostream& os) const; + void print_pretty(::std::ostream& os, bool is_type_context) const; friend ::std::ostream& operator<<(::std::ostream& os, const Path& path); friend ::Serialiser& operator<<(Serialiser& s, Path::Class pc); friend void operator>>(Deserialiser& s, Path::Class& pc); diff --git a/src/convert/resolve.cpp b/src/convert/resolve.cpp index 629f7f12..6a544713 100644 --- a/src/convert/resolve.cpp +++ b/src/convert/resolve.cpp @@ -967,10 +967,12 @@ void CPathResolver::handle_path_abs__into_ufcs(const Span& span, AST::Path& path DEBUG("type_path = " << type_path << ", nodes[i] = " << nodes[i]);
resolve_path(span, m_crate, type_path);
// If the type path refers to a trait, put it in the trait location
- if(type_path.binding().is_Trait())
+ if(type_path.binding().is_Trait()) {
type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(), TypeRef(mv$(type_path)), {mv$(nodes[i])} );
- else
+ }
+ else {
type_path = AST::Path(AST::Path::TagUfcs(), TypeRef(mv$(type_path)), TypeRef(), {mv$(nodes[i])} );
+ }
}
path = mv$(type_path);
@@ -1008,8 +1010,10 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter // - Impl heads and trait heads could be resolved in an earlier pass
if( info.trait->is_wildcard() )
{
- #if 0
+ // 1. Search inherent impls
+ // 2. If doing a late pass (after module-level names are resolved) search for traits
if( this->m_second_pass ) {
+ #if 0
const ::std::string& item_name = info.nodes[0].name();
DEBUG("Searching for matching trait for '"<<item_name<<"' on type " << *info.type);
@@ -1122,8 +1126,31 @@ void CPathResolver::handle_path_ufcs(const Span& span, AST::Path& path, CASTIter throw ParseError::Todo( FMT("CPathResolver::handle_path_ufcs - UFCS, find trait, for type " << *info.type) );
}
+ #endif
+ }
+ else
+ {
+ const auto& name = path.nodes()[0].name();
+ if( info.type->is_path() )
+ {
+ // 1. Search for enum constructors
+ TU_MATCH_DEF(AST::PathBinding, (info.type->path().binding()), (i),
+ ( ),
+ (Enum,
+ const auto& e = *i.enum_;
+ for(const auto& var : e.variants())
+ {
+ if( var.m_name == name ) {
+ path.bind_enum_var(e, name);
+ info.trait = make_unique_ptr( TypeRef(TypeRef::TagInvalid()) );
+ return ;
+ }
+ }
+ )
+ )
+
+ }
}
- #endif
}
else {
#if 0
@@ -1231,8 +1258,24 @@ void CPathResolver::handle_path_rel(const Span& span, AST::Path& path, CASTItera path = AST::Path(AST::Path::TagLocal(), path[0].name());
return ;
}
+
+ // 5. Check if the unresolved name is a primitive type
+ {
+ if( path[0].name() == "str" ) {
+ TODO(span, "Expand `str` to internal path");
+ }
+ else if( auto ct = coretype_fromstring(path[0].name()) ) {
+ auto ty = TypeRef(TypeRef::TagPrimitive(), ct);
+ auto newpath = AST::Path(AST::Path::TagUfcs(), ty, TypeRef());
+ newpath.add_tailing(path);
+ path = mv$(newpath);
+ return ;
+ }
+ else {
+ }
+ }
- // 5. Otherwise, error
+ // Z. Otherwise, error
ERROR(span, E0000, "CPathResolver::handle_path - Name resolution failed");
}
@@ -1382,6 +1425,7 @@ void CPathResolver::handle_type(TypeRef& type) }
else if( name == "Self" )
{
+ // TODO: Should I always resolve `Self` when it's concretely known?
// If the name was "Self", but Self isn't already defined... then we need to make it an arg?
if( this->m_self_type.empty() || this->m_self_type.back().is_None() ) {
ERROR(type.path().span(), E0000, "Unexpected 'Self'");
diff --git a/src/coretypes.hpp b/src/coretypes.hpp index 2fc11412..1d3cba67 100644 --- a/src/coretypes.hpp +++ b/src/coretypes.hpp @@ -19,6 +19,7 @@ enum eCoreType CORETYPE_F64,
};
+extern enum eCoreType coretype_fromstring(const ::std::string& name);
extern const char* coretype_name(const eCoreType ct);
extern void operator% (::Serialiser& d, eCoreType ct);
extern void operator% (::Deserialiser& d, eCoreType& ct);
diff --git a/src/dump_as_rust.cpp b/src/dump_as_rust.cpp index 41043515..fee1ac34 100644 --- a/src/dump_as_rust.cpp +++ b/src/dump_as_rust.cpp @@ -8,7 +8,11 @@ #include "ast/expr.hpp" #include <main_bindings.hpp> +#include <cpp_unpack.h> + #define IS(v, c) (dynamic_cast<c*>(&v) != 0) +#define WRAPIF_CMD(v, t) || IS(v, t) +#define WRAPIF(uniq_ptr, class1, ...) do { auto& _v = *(uniq_ptr); if( IS(_v, class1) CC_ITERATE(WRAPIF_CMD, (_v), __VA_ARGS__) ) { paren_wrap(uniq_ptr); } else { AST::NodeVisitor::visit(uniq_ptr); } } while(0) class RustPrinter: public AST::NodeVisitor @@ -32,6 +36,9 @@ public: virtual bool is_const() const override { return true; } virtual void visit(AST::ExprNode_Block& n) override { + if( n.m_is_unsafe ) { + m_os << "unsafe "; + } m_os << "{"; inc_indent(); if( n.m_inner_mod.get() ) @@ -118,9 +125,12 @@ public: } virtual void visit(AST::ExprNode_CallMethod& n) override { m_expr_root = false; - m_os << "("; - AST::NodeVisitor::visit(n.m_val); - m_os << ")." << n.m_method; + WRAPIF( n.m_val + , AST::ExprNode_Deref, AST::ExprNode_UniOp + , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign + , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match + ); + m_os << "." << n.m_method; m_os << "("; bool is_first = true; for( auto& arg : n.m_args ) @@ -419,15 +429,21 @@ public: } virtual void visit(AST::ExprNode_Field& n) override { m_expr_root = false; - m_os << "("; - AST::NodeVisitor::visit(n.m_obj); - m_os << ")." << n.m_name; + WRAPIF( n.m_obj + , AST::ExprNode_Deref, AST::ExprNode_UniOp + , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign + , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match + ); + m_os << "." << n.m_name; } virtual void visit(AST::ExprNode_Index& n) override { m_expr_root = false; - m_os << "("; - AST::NodeVisitor::visit(n.m_obj); - m_os << ")["; + WRAPIF( n.m_obj + , AST::ExprNode_Deref, AST::ExprNode_UniOp + , AST::ExprNode_Cast, AST::ExprNode_BinOp, AST::ExprNode_Assign + , AST::ExprNode_Match, AST::ExprNode_If, AST::ExprNode_IfLet, AST::ExprNode_Match + ); + m_os << "["; AST::NodeVisitor::visit(n.m_idx); m_os << "]"; } @@ -444,12 +460,9 @@ public: } virtual void visit(AST::ExprNode_BinOp& n) override { m_expr_root = false; - if( IS(*n.m_left, AST::ExprNode_Cast) ) - paren_wrap(n.m_left); - else if( IS(*n.m_left, AST::ExprNode_BinOp) ) - paren_wrap(n.m_left); - else - AST::NodeVisitor::visit(n.m_left); + WRAPIF(n.m_left + , AST::ExprNode_Cast, AST::ExprNode_BinOp + ); m_os << " "; switch(n.m_type) { diff --git a/src/include/cpp_unpack.h b/src/include/cpp_unpack.h new file mode 100644 index 00000000..d5087668 --- /dev/null +++ b/src/include/cpp_unpack.h @@ -0,0 +1,33 @@ + +#ifndef _CPP_UNAPCK_H_ +#define _CPP_UNAPCK_H_ + +#define CC_EXP(...) __VA_ARGS__ + +// - Calls the passed function, expanding 'a' but leaving _1 as a single argument +#define CC_CALL_A(__fcn, __args) __fcn __args +#define CC_CALL_A1(f, a, _1) CC_CALL_A(f, (CC_EXP a, _1)) +#define CC_CALL_A2(f, a, _1, _2) CC_CALL_A(f, (CC_EXP a, _1)) CC_CALL_A(f, (CC_EXP a, _2)) +#define CC_CALL_A3(f, a, _1, _2, _3) CC_CALL_A(f, (CC_EXP a, _1)) CC_CALL_A(f, (CC_EXP a, _2)) CC_CALL_A(f, (CC_EXP a, _3)) + +#define CC_CALL_A4(fn, a, a1,a2, b1,b2) CC_CALL_A2(fn,a, a1,a2) CC_CALL_A2(fn,a, b1,b2) +#define CC_CALL_A5(fn, a, a1,a2,a3, b1,b2) CC_CALL_A3(fn,a, a1,a2,a3) CC_CALL_A2(fn,a, b1,b2) +#define CC_CALL_A6(fn, a, a1,a2,a3, b1,b2,b3) CC_CALL_A3(fn,a, a1,a2,a3) CC_CALL_A3(fn,a, b1,b2,b3) +#define CC_CALL_A7(fn, a, a1,a2,a3, b1,b2, c1,c2) CC_CALL_A3(fn,a, a1,a2,a3) CC_CALL_A2(fn,a, b1,b2) CC_CALL_A2(fn,a, c1,c2) +#define CC_CALL_A8(fn, a, a1,a2,a3, b1,b2,b3, c1,c2) CC_CALL_A3(fn,a, a1,a2,a3) CC_CALL_A3(fn,a, b1,b2,b3) CC_CALL_A2(fn,a, c1,c2) +#define CC_CALL_A9(fn, a, a1,a2,a3, b1,b2,b3, c1,c2,c3) CC_CALL_A3(fn,a, a1,a2,a3) CC_CALL_A3(fn,a, b1,b2,b3) CC_CALL_A3(fn,a, c1,c2,c3) +#define CC_CALL_A10(f, a, a1,a2,a3, b1,b2,b3, c1,c2,c3, d1) CC_CALL_A3(f,a, a1,a2,a3) CC_CALL_A3(f,a, b1,b2,b3) CC_CALL_A3(f,a, c1,c2,c3) CC_CALL_A(f, (CC_EXP a, CC_EXP d1)) +#define CC_CALL_A11(f, a, a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2) CC_CALL_A3(f,a, a1,a2,a3) CC_CALL_A3(f,a, b1,b2,b3) CC_CALL_A3(f,a, c1,c2,c3) CC_CALL_A2(f,a, d1,d2) +#define CC_CALL_A12(f, a, a1,a2,a3, b1,b2,b3, c1,c2,c3, d1,d2,d3) CC_CALL_A3(f,a, a1,a2,a3) CC_CALL_A3(f,a, b1,b2,b3) CC_CALL_A3(f,a, c1,c2,c3) CC_CALL_A3(f,a, d1,d2,d3) +#define CC_CALL_A13(f, a, a1,a2,a3,a4, b1,b2,b3, c1,c2,c3, d1,d2,d3) CC_CALL_A4(f,a, a1,a2,a3,a4) CC_CALL_A3(f,a, b1,b2,b3) CC_CALL_A3(f,a, c1,c2,c3) CC_CALL_A3(f,a, d1,d2,d3) +#define CC_CALL_A14(f, a, a1,a2,a3,a4, b1,b2,b3,b4, c1,c2,c3, d1,d2,d3) CC_CALL_A4(f,a, a1,a2,a3,a4) CC_CALL_A4(f,a, b1,b2,b3,b4) CC_CALL_A3(f,a, c1,c2,c3) CC_CALL_A3(f,a, d1,d2,d3) + +// Macro to obtain a numbered macro for argument counts +// - Raw variant +#define CC_GM_I(SUF,_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,_11,_12,_13,_14,_15,_16,COUNT,...) SUF##COUNT +#define CC_GM(SUF,...) CC_GM_I(SUF,__VA_ARGS__,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1) + +#define CC_ITERATE(fcn, args, ...) CC_EXP( CC_GM(CC_CALL_A, __VA_ARGS__)(fcn, args, __VA_ARGS__) ) + +#endif + diff --git a/src/include/span.hpp b/src/include/span.hpp index 7a4c60b0..7603b080 100644 --- a/src/include/span.hpp +++ b/src/include/span.hpp @@ -61,4 +61,5 @@ struct Spanned #define ERROR(span, code, msg) do { (Span()/*span*/).error(code, [&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Error fell through" #code); } while(0) #define BUG(span, msg) do { (span).bug([&](::std::ostream& os) { os << msg; }); throw ::std::runtime_error("Bug fell through"); } while(0) +#define TODO(span, msg) do { (span).bug([&](::std::ostream& os) { os << "TODO: " << msg; }); throw ::std::runtime_error("Bug (todo) fell through"); } while(0) diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 91b7e646..045ecd96 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -8,6 +8,8 @@ #ifndef INCLUDED_TAGGED_UNION_H_ #define INCLUDED_TAGGED_UNION_H_ +//#include "cpp_unpack.h" + #define TU_CASE_ITEM(src, mod, var, name) mod auto& name = src.as_##var(); (void)&name; #define TU_CASE_BODY(class,var, ...) case class::var: { __VA_ARGS__ } break; #define TU_CASE(mod, class, var, name,src, ...) TU_CASE_BODY(mod,class,var, TU_CASE_ITEM(src,mod,var,name) __VA_ARGS__) @@ -18,8 +20,8 @@ // Argument iteration #define _DISP1(n, _1) n _1 #define _DISP2(n, _1, _2) n _1 n _2 -#define _DISP3(n, v, v2, v3) n v n v2 n v3 // _DISP2(n, __VA_ARGS__) -#define _DISP4(n, v, v2, v3, v4) n v n v2 n v3 n v4 // #define _DISP4(n, v, ...) n v _DISP3(n, __VA_ARGS__) +#define _DISP3(n, v, v2, v3) n v n v2 n v3 +#define _DISP4(n, v, v2, v3, v4) n v n v2 n v3 n v4 #define _DISP5(n, v, ...) n v _DISP4(n, __VA_ARGS__) #define _DISP6(n, v, ...) n v _DISP5(n, __VA_ARGS__) #define _DISP7(n, v, ...) n v _DISP6(n, __VA_ARGS__) diff --git a/src/parse/lex.cpp b/src/parse/lex.cpp index 9855e3c0..a3187cda 100644 --- a/src/parse/lex.cpp +++ b/src/parse/lex.cpp @@ -180,8 +180,6 @@ signed int Lexer::getSymbol() const char* const chars = TOKENMAP[i].chars; const size_t len = TOKENMAP[i].len; - //::std::cout << "ofs=" << ofs << ", chars[ofs] = " << chars[ofs] << ", ch = " << ch << ", len = " << len << ::std::endl; - if( ofs >= len || chars[ofs] > ch ) { this->ungetc(); return best; @@ -370,6 +368,7 @@ Token Lexer::getTokenInt() // Single dot else if( !isdigit(ch) ) { + this->ungetc(); this->m_next_token = Token(TOK_DOT); return Token(val, CORETYPE_ANY); } diff --git a/src/parse/types.cpp b/src/parse/types.cpp index d0ca6357..532cccae 100644 --- a/src/parse/types.cpp +++ b/src/parse/types.cpp @@ -10,29 +10,6 @@ #include "../types.hpp" #include "../ast/ast.hpp" -/// Mappings from internal type names to the core type enum -static const struct { - const char* name; - enum eCoreType type; -} CORETYPES[] = { - {"bool", CORETYPE_BOOL}, - {"char", CORETYPE_CHAR}, - {"f32", CORETYPE_F32}, - {"f64", CORETYPE_F64}, - {"i16", CORETYPE_I16}, - {"i32", CORETYPE_I32}, - {"i64", CORETYPE_I64}, - {"i8", CORETYPE_I8}, - {"int", CORETYPE_INT}, - {"isize", CORETYPE_INT}, - {"u16", CORETYPE_U16}, - {"u32", CORETYPE_U32}, - {"u64", CORETYPE_U64}, - {"u8", CORETYPE_U8}, - {"uint", CORETYPE_UINT}, - {"usize", CORETYPE_UINT}, -}; - // === PROTOTYPES === TypeRef Parse_Type(TokenStream& lex); TypeRef Parse_Type_Int(TokenStream& lex); @@ -77,35 +54,15 @@ TypeRef Parse_Type_Int(TokenStream& lex) case TOK_LT: lex.putback(tok); return TypeRef(TypeRef::TagPath(), Parse_Path(lex, PATH_GENERIC_TYPE)); - #if 0 - { - DEBUG("Associated type"); - // TODO: This should instead use the path code, not a special case in typing - // <Type as Trait>::Inner - TypeRef base = Parse_Type(lex); - GET_CHECK_TOK(tok, lex, TOK_RWORD_AS); - TypeRef trait = Parse_Type(lex); - GET_CHECK_TOK(tok, lex, TOK_GT); - // TODO: Is just '<Type as Trait>' valid? - GET_CHECK_TOK(tok, lex, TOK_DOUBLE_COLON); - GET_CHECK_TOK(tok, lex, TOK_IDENT); - ::std::string inner_name = tok.str(); - return TypeRef(TypeRef::TagAssoc(), ::std::move(base), ::std::move(trait), ::std::move(inner_name)); - } - #endif // <ident> - Either a primitive, or a path case TOK_IDENT: // or a primitive - for(unsigned int i = 0; i < sizeof(CORETYPES)/sizeof(CORETYPES[0]); i ++) + if( auto ct = coretype_fromstring(tok.str()) ) { - if( tok.str() < CORETYPES[i].name ) - break; - if( tok.str() == CORETYPES[i].name ) - return TypeRef(TypeRef::TagPrimitive(), CORETYPES[i].type); + return TypeRef(TypeRef::TagPrimitive(), ct); } if( tok.str() == "str" ) { - // TODO: Create an internal newtype for 'str' return TypeRef(TypeRef::TagPath(), AST::Path("", { AST::PathNode("#",{}), AST::PathNode("str",{}) })); } // - Fall through to path handling diff --git a/src/types.cpp b/src/types.cpp index 7e2a835e..882caef5 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -10,6 +10,41 @@ #include "types.hpp" #include "ast/ast.hpp" +/// Mappings from internal type names to the core type enum +static const struct { + const char* name; + enum eCoreType type; +} CORETYPES[] = { + {"bool", CORETYPE_BOOL}, + {"char", CORETYPE_CHAR}, + {"f32", CORETYPE_F32}, + {"f64", CORETYPE_F64}, + {"i16", CORETYPE_I16}, + {"i32", CORETYPE_I32}, + {"i64", CORETYPE_I64}, + {"i8", CORETYPE_I8}, + {"int", CORETYPE_INT}, + {"isize", CORETYPE_INT}, + {"u16", CORETYPE_U16}, + {"u32", CORETYPE_U32}, + {"u64", CORETYPE_U64}, + {"u8", CORETYPE_U8}, + {"uint", CORETYPE_UINT}, + {"usize", CORETYPE_UINT}, +}; + +enum eCoreType coretype_fromstring(const ::std::string& name) +{ + for(unsigned int i = 0; i < sizeof(CORETYPES)/sizeof(CORETYPES[0]); i ++) + { + if( name < CORETYPES[i].name ) + break; + if( name == CORETYPES[i].name ) + return CORETYPES[i].type; + } + return CORETYPE_INVAL; +} + const char* coretype_name(const eCoreType ct ) { switch(ct) { |