Skip to content

Commit acc8782

Browse files
authored
Merge pull request #282 from Pivot-Studio/Chronostasys/issue280
feat: supports tuple type
2 parents 5688476 + 54610c0 commit acc8782

File tree

16 files changed

+387
-39
lines changed

16 files changed

+387
-39
lines changed

src/ast/builder/llvmbuilder.rs

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
222222
size_val,
223223
)
224224
.unwrap();
225-
if let PLType::Struct(_) = pltype {
226-
let f = self.get_or_insert_st_visit_fn_handle(&p);
225+
if let PLType::Struct(tp) = pltype {
226+
let f = self.get_or_insert_st_visit_fn_handle(&p, tp);
227227
let i = self.builder.build_ptr_to_int(
228228
f.as_global_value().as_pointer_value(),
229229
self.context.i64_type(),
@@ -526,10 +526,13 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
526526
PriType::BOOL => self.context.bool_type().as_basic_type_enum(),
527527
}
528528
}
529-
fn get_or_insert_st_visit_fn_handle(&self, p: &PointerValue<'ctx>) -> FunctionValue<'ctx> {
529+
fn get_or_insert_st_visit_fn_handle(
530+
&self,
531+
p: &PointerValue<'ctx>,
532+
st: &STType,
533+
) -> FunctionValue<'ctx> {
530534
let ptrtp = p.get_type();
531-
let ty = ptrtp.get_element_type().into_struct_type();
532-
let llvmname = ty.get_name().unwrap().to_str().unwrap().to_string() + "@";
535+
let llvmname = st.get_st_full_name() + "@";
533536
if let Some(v) = self.module.get_function(&llvmname) {
534537
return v;
535538
}
@@ -948,32 +951,37 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
948951
self.module
949952
.add_function(&llvmname, fn_type, Some(Linkage::External))
950953
}
954+
fn get_fields(&self, pltp: &STType, ctx: &mut Ctx<'a>) -> Vec<BasicTypeEnum> {
955+
ctx.run_in_type_mod(pltp, |ctx, pltp| {
956+
pltp.get_all_field()
957+
.iter()
958+
.map(|order_field| {
959+
self.get_basic_type_op(
960+
&order_field
961+
.typenode
962+
.get_type(ctx, &self.clone().into())
963+
.unwrap()
964+
.borrow(),
965+
ctx,
966+
)
967+
.unwrap()
968+
})
969+
.collect::<Vec<_>>()
970+
})
971+
}
972+
951973
fn struct_type(&self, pltp: &STType, ctx: &mut Ctx<'a>) -> StructType<'ctx> {
952974
let st = self.module.get_struct_type(&pltp.get_st_full_name());
953975
if let Some(st) = st {
954976
return st;
955977
}
978+
979+
if pltp.is_tuple {
980+
let fields = &self.get_fields(pltp, ctx);
981+
return self.context.struct_type(fields, false);
982+
}
956983
let st = self.context.opaque_struct_type(&pltp.get_st_full_name());
957-
ctx.run_in_type_mod(pltp, |ctx, pltp| {
958-
st.set_body(
959-
&pltp
960-
.get_all_field()
961-
.iter()
962-
.map(|order_field| {
963-
self.get_basic_type_op(
964-
&order_field
965-
.typenode
966-
.get_type(ctx, &self.clone().into())
967-
.unwrap()
968-
.borrow(),
969-
ctx,
970-
)
971-
.unwrap()
972-
})
973-
.collect::<Vec<_>>(),
974-
false,
975-
);
976-
});
984+
st.set_body(&self.get_fields(pltp, ctx), false);
977985
st
978986
}
979987

@@ -1716,11 +1724,9 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17161724
let ptrtp = self.struct_type(v, ctx).ptr_type(AddressSpace::default());
17171725
let ty = ptrtp.get_element_type().into_struct_type();
17181726
let ftp = self.mark_fn_tp(ptrtp);
1719-
let f = self.module.add_function(
1720-
&(ty.get_name().unwrap().to_str().unwrap().to_string() + "@"),
1721-
ftp,
1722-
None,
1723-
);
1727+
let f = self
1728+
.module
1729+
.add_function(&(v.get_st_full_name() + "@"), ftp, None);
17241730
let bb = self.context.append_basic_block(f, "entry");
17251731
self.builder.position_at_end(bb);
17261732
let fieldn = ty.count_fields();

src/ast/ctx.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,9 @@ impl<'a, 'ctx> Ctx<'a> {
633633
}
634634

635635
pub fn send_if_go_to_def(&self, range: Range, destrange: Range, file: String) {
636+
if range == Default::default() {
637+
return;
638+
}
636639
self.plmod.defs.borrow_mut().insert(
637640
range,
638641
LSPDef::Scalar(Location {

src/ast/diag.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hash::FxHashMap;
77
use std::{
88
collections::HashMap,
99
fmt::{Display, Formatter},
10+
process::exit,
1011
};
1112
macro_rules! define_error {
1213
($(
@@ -476,13 +477,14 @@ pub(crate) fn handle_errors(db: &dyn Db, docs: MemDocsInput) {
476477
format!("compile failed: there is {} error", errs_num).bright_red()
477478
);
478479
println!("{}", dot::ERROR);
479-
return;
480+
exit(1);
480481
}
481482
log::error!(
482483
"{}",
483484
format!("compile failed: there are {} errors", errs_num).bright_red()
484485
);
485486
println!("{}", dot::TOOMANYERROR);
487+
exit(1);
486488
}
487489
}
488490
}

src/ast/fmt.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use super::{
2222
ret::RetNode,
2323
statement::{AssignNode, DefNode, EmptyNode, StatementsNode},
2424
string_literal::StringNode,
25+
tuple::{TupleInitNode, TupleTypeNode},
2526
types::{
2627
ArrayInitNode, ArrayTypeNameNode, GenericDefNode, GenericParamNode, PointerTypeNode,
2728
StructDefNode, StructInitFieldNode, StructInitNode, TypeNameNode, TypedIdentifierNode,
@@ -745,4 +746,26 @@ impl FmtBuilder {
745746
self.space();
746747
node.ty.format(self);
747748
}
749+
pub fn parse_tuple_init_node(&mut self, node: &TupleInitNode) {
750+
self.l_paren();
751+
for (i, expr) in node.exprs.iter().enumerate() {
752+
if i > 0 {
753+
self.comma();
754+
self.space();
755+
}
756+
expr.format(self);
757+
}
758+
self.r_paren();
759+
}
760+
pub fn parse_tuple_type_node(&mut self, node: &TupleTypeNode) {
761+
self.l_paren();
762+
for (i, ty) in node.tps.iter().enumerate() {
763+
if i > 0 {
764+
self.comma();
765+
self.space();
766+
}
767+
ty.format(self);
768+
}
769+
self.r_paren();
770+
}
748771
}

src/ast/node/interface.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ impl MultiTraitNode {
4141
modifier: None,
4242
body_range: Default::default(),
4343
is_trait: true,
44+
is_tuple: false,
4445
};
4546
builder.opaque_struct_type(&ctx.plmod.get_full_name(&name));
4647
builder.add_body_to_struct_type(&ctx.plmod.get_full_name(&name), &st, ctx);
@@ -164,6 +165,7 @@ impl TraitDefNode {
164165
modifier: self.modifier,
165166
body_range: self.range(),
166167
is_trait: true,
168+
is_tuple: false,
167169
})));
168170
builder.opaque_struct_type(&ctx.plmod.get_full_name(&self.id.name));
169171
_ = ctx.add_type(self.id.name.clone(), stu, self.id.range);

src/ast/node/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ use self::primary::*;
3232
use self::ret::*;
3333
use self::statement::*;
3434
use self::string_literal::StringNode;
35+
use self::tuple::TupleInitNode;
36+
use self::tuple::TupleTypeNode;
3537
use self::types::*;
3638
use self::union::UnionDefNode;
3739

@@ -60,6 +62,7 @@ pub mod program;
6062
pub mod ret;
6163
pub mod statement;
6264
pub mod string_literal;
65+
pub mod tuple;
6366
pub mod types;
6467
pub mod union;
6568

@@ -70,6 +73,7 @@ pub enum TypeNodeEnum {
7073
Array(ArrayTypeNameNode),
7174
Pointer(PointerTypeNode),
7275
Func(FuncDefNode),
76+
Tuple(TupleTypeNode),
7377
}
7478
#[enum_dispatch]
7579
pub trait TypeNode: RangeTrait + FmtTrait + PrintTrait {
@@ -134,6 +138,7 @@ pub enum NodeEnum {
134138
UnionDefNode(UnionDefNode),
135139
AsNode(AsNode),
136140
IsNode(IsNode),
141+
TupleInitNode(TupleInitNode),
137142
}
138143
// ANCHOR: range
139144
#[enum_dispatch]

0 commit comments

Comments
 (0)