Skip to content

Commit 2f12458

Browse files
committed
Merge branch 'feature/extern_type' into development
2 parents d95f4fa + ccbf98d commit 2f12458

File tree

11 files changed

+123
-0
lines changed

11 files changed

+123
-0
lines changed

include/artic/ast.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,28 @@ struct TypeDecl : public NamedDecl {
15061506
void print(Printer&) const override;
15071507
};
15081508

1509+
struct ExtTypeDecl : public NamedDecl {
1510+
Ptr<TypeParamList> type_params;
1511+
PtrVector<std::string> type_args;
1512+
1513+
ExtTypeDecl(
1514+
const Loc& loc,
1515+
Identifier&& id,
1516+
Ptr<TypeParamList>&& type_params,
1517+
PtrVector<std::string>&& type_args)
1518+
: NamedDecl(loc, std::move(id))
1519+
, type_params(std::move(type_params))
1520+
, type_args(std::move(type_args))
1521+
{}
1522+
1523+
const thorin::Def* emit(Emitter&) const override;
1524+
const artic::Type* infer(TypeChecker&) override;
1525+
void bind_head(NameBinder&) override;
1526+
void bind(NameBinder&) override;
1527+
void resolve_summons(Summoner&) override {};
1528+
void print(Printer&) const override;
1529+
};
1530+
15091531
/// Module definition.
15101532
struct ModDecl : public NamedDecl {
15111533
PtrVector<Decl> decls;

include/artic/parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class Parser : public Logger {
3434
Ptr<ast::ImplicitDecl> parse_implicit_decl();
3535
Ptr<ast::StaticDecl> parse_static_decl();
3636
Ptr<ast::TypeDecl> parse_type_decl();
37+
Ptr<ast::ExtTypeDecl> parse_ext_type_decl();
3738
Ptr<ast::TypeParam> parse_type_param();
3839
Ptr<ast::TypeParamList> parse_type_params();
3940
Ptr<ast::ModDecl> parse_mod_decl();

include/artic/token.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace artic {
3030
f(Struct, "struct") \
3131
f(Enum, "enum") \
3232
f(Type, "type") \
33+
f(TypeExt, "type_ext") \
3334
f(Static, "static") \
3435
f(Implicit, "implicit") \
3536
f(Summon, "summon") \

include/artic/types.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,22 @@ struct TypeAlias : public PolyTypeFromDecl<UserType, ast::TypeDecl> {
582582
friend class TypeTable;
583583
};
584584

585+
struct ExtType : public PolyTypeFromDecl<UserType, ast::ExtTypeDecl> {
586+
void print(Printer&) const override;
587+
588+
private:
589+
ExtType(TypeTable& type_table, const ast::ExtTypeDecl& decl)
590+
: PolyTypeFromDecl(type_table, decl)
591+
{}
592+
593+
using UserType::convert;
594+
const thorin::Type* convert(Emitter&, const Type*) const override;
595+
596+
std::string stringify(Emitter&) const override;
597+
598+
friend class TypeTable;
599+
};
600+
585601
/// An application of a complex type with polymorphic parameters.
586602
struct TypeApp : public Type {
587603
const UserType* applied;
@@ -684,6 +700,7 @@ class TypeTable {
684700
const EnumType* enum_type(const ast::EnumDecl&);
685701
const ModType* mod_type(const ast::ModDecl&);
686702
const TypeAlias* type_alias(const ast::TypeDecl&);
703+
const ExtType* ext_type(const ast::ExtTypeDecl&);
687704

688705
/// Creates a type application for structures/enumeration types,
689706
/// or returns the type alias expanded with the given type arguments.

src/bind.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,23 @@ void TypeDecl::bind_head(NameBinder& binder) {
509509
binder.insert_symbol(*this);
510510
}
511511

512+
void ExtTypeDecl::bind_head(NameBinder& binder) {
513+
binder.insert_symbol(*this);
514+
}
515+
512516
void TypeDecl::bind(NameBinder& binder) {
513517
binder.push_scope();
514518
if (type_params) binder.bind(*type_params);
515519
binder.bind(*aliased_type);
516520
binder.pop_scope();
517521
}
518522

523+
void ExtTypeDecl::bind(NameBinder& binder) {
524+
binder.push_scope();
525+
if (type_params) binder.bind(*type_params);
526+
binder.pop_scope();
527+
}
528+
519529
void ModDecl::bind_head(NameBinder& binder) {
520530
if (id.name != "")
521531
binder.insert_symbol(*this);

src/check.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1816,6 +1816,11 @@ const artic::Type* TypeDecl::infer(TypeChecker& checker) {
18161816
return type;
18171817
}
18181818

1819+
const artic::Type* ExtTypeDecl::infer(TypeChecker& checker) {
1820+
const artic::Type* type = checker.type_table.ext_type(*this);
1821+
return type;
1822+
}
1823+
18191824
const artic::Type* ModDecl::infer(TypeChecker& checker) {
18201825
for (auto& decl : decls)
18211826
checker.infer(*decl);

src/emit.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,10 @@ const thorin::Def* TypeDecl::emit(Emitter&) const {
17781778
return nullptr;
17791779
}
17801780

1781+
const thorin::Def* ExtTypeDecl::emit(Emitter&) const {
1782+
return nullptr;
1783+
}
1784+
17811785
const thorin::Def* ModDecl::emit(Emitter& emitter) const {
17821786
for (auto& decl : decls) {
17831787
// Do not emit polymorphic functions directly: Those will be emitted from
@@ -2054,6 +2058,26 @@ const thorin::Type* TypeApp::convert(Emitter& emitter) const {
20542058
return result;
20552059
}
20562060

2061+
std::string ExtType::stringify(Emitter& emitter) const {
2062+
if (!type_params())
2063+
return decl.id.name;
2064+
return stringify_params(emitter, decl.id.name + "_", type_params()->params);
2065+
}
2066+
2067+
const thorin::Type* ExtType::convert(Emitter& emitter, const Type* parent) const {
2068+
if (auto it = emitter.types.find(this); !type_params() && it != emitter.types.end())
2069+
return it->second;
2070+
2071+
std::vector<std::string> args;
2072+
for (auto& arg : decl.type_args) {
2073+
args.emplace_back(*arg);
2074+
}
2075+
2076+
auto type = emitter.world.extern_type(decl.id.name, args);
2077+
emitter.types[parent] = type;
2078+
return type;
2079+
}
2080+
20572081
// A read-only buffer from memory, not performing any copy.
20582082
struct MemBuf : public std::streambuf {
20592083
MemBuf(const std::string& str) {

src/lexer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ std::unordered_map<std::string, Token::Tag> Lexer::keywords{
2323
std::make_pair("struct", Token::Struct),
2424
std::make_pair("enum", Token::Enum),
2525
std::make_pair("type", Token::Type),
26+
std::make_pair("type_ext", Token::TypeExt),
2627
std::make_pair("implicit", Token::Implicit),
2728
std::make_pair("summon", Token::Summon),
2829
std::make_pair("static", Token::Static),

src/parser.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Ptr<ast::Decl> Parser::parse_decl(bool is_top_level) {
4242
case Token::Struct: decl = parse_struct_decl(); break;
4343
case Token::Enum: decl = parse_enum_decl(); break;
4444
case Token::Type: decl = parse_type_decl(); break;
45+
case Token::TypeExt: decl = parse_ext_type_decl(); break;
4546
case Token::Implicit: decl = parse_implicit_decl(); break;
4647
case Token::Static: decl = parse_static_decl(); break;
4748
case Token::Mod: decl = parse_mod_decl(); break;
@@ -200,6 +201,28 @@ Ptr<ast::TypeDecl> Parser::parse_type_decl() {
200201
return _arena.make_ptr<ast::TypeDecl>(tracker(), std::move(id), std::move(type_params), std::move(aliased_type));
201202
}
202203

204+
Ptr<ast::ExtTypeDecl> Parser::parse_ext_type_decl() {
205+
Tracker tracker(this);
206+
eat(Token::TypeExt);
207+
auto id = parse_id();
208+
209+
Ptr<ast::TypeParamList> type_params;
210+
if (ahead().tag() == Token::LBracket)
211+
type_params = parse_type_params();
212+
213+
PtrVector<std::string> type_args;
214+
if (accept(Token::Eq)) {
215+
expect(Token::LBrace);
216+
217+
parse_list(Token::RBrace, Token::Comma, [&] {
218+
type_args.emplace_back(_arena.make_ptr<std::string>(parse_str()));
219+
});
220+
}
221+
222+
expect(Token::Semi);
223+
return _arena.make_ptr<ast::ExtTypeDecl>(tracker(), std::move(id), std::move(type_params), std::move(type_args));
224+
}
225+
203226
Ptr<ast::ImplicitDecl> Parser::parse_implicit_decl() {
204227
Tracker tracker(this);
205228
eat(Token::Implicit);

src/print.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,17 @@ void TypeDecl::print(Printer& p) const {
614614
p << ';';
615615
}
616616

617+
void ExtTypeDecl::print(Printer& p) const {
618+
if (attrs) attrs->print(p);
619+
p << log::keyword_style("type_ext") << ' ' << id.name;
620+
if (type_params) type_params->print(p);
621+
p << " = { ";
622+
print_list(p, ',', type_args, [&] (auto& arg) {
623+
p << *arg;
624+
});
625+
p << " };";
626+
}
627+
617628
void ModDecl::print(Printer& p) const {
618629
if (attrs) attrs->print(p);
619630
bool anon = id.name == "";
@@ -825,6 +836,10 @@ void TypeAlias::print(Printer& p) const {
825836
p << decl.id.name;
826837
}
827838

839+
void ExtType::print(Printer& p) const {
840+
p << decl.id.name;
841+
}
842+
828843
void TypeApp::print(Printer& p) const {
829844
applied->print(p);
830845
p << '[';

0 commit comments

Comments
 (0)