summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ast/path.cpp101
-rw-r--r--src/ast/path.hpp5
-rw-r--r--src/convert/resolve.cpp54
-rw-r--r--src/coretypes.hpp1
-rw-r--r--src/dump_as_rust.cpp43
-rw-r--r--src/include/cpp_unpack.h33
-rw-r--r--src/include/span.hpp1
-rw-r--r--src/include/tagged_union.hpp6
-rw-r--r--src/parse/lex.cpp3
-rw-r--r--src/parse/types.cpp47
-rw-r--r--src/types.cpp35
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)
{