Skip to content

Commit 0d346ff

Browse files
committed
refactor: bug fix resolver of the method_call in analyzer
1 parent 974782a commit 0d346ff

File tree

12 files changed

+310
-120
lines changed

12 files changed

+310
-120
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ static-analyzer:
44
cargo run -j24 -p static_analyzer -- ./examples/main.cyr
55

66
emit-llvm:
7-
cargo run -j24 -- emit-llvm ./examples/main.cyr -o ./tmp/llvmir/ --stdlib=./stdlib --disable-modulefs-cache
7+
cargo run -j24 -- emit-llvm ./examples/main.cyr -o ./tmp/llvmir/ --stdlib=./stdlib
88

99
parser:
1010
cargo run -j24 -p parser -- ./examples/main.cyr --stdlib=./stdlib
1111

1212
run:
13-
cargo run -j24 -p cli -- run ./examples/main.cyr --stdlib=./stdlib
13+
cargo run -j24 -p cli -- run ./examples/main.cyr --stdlib=./stdlib --disable-warnings
1414

1515
test:
1616
cargo test -j24 --all

crates/codegen/src/builder/abi.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
1-
pub(crate) fn make_func_abi_name(module_name: String, func_name: String) -> String {
2-
format!("{}.{}", module_name, func_name)
1+
use ast::AccessSpecifier;
2+
3+
pub(crate) fn make_func_abi_name(module_name: String, func_name: String, vis: AccessSpecifier) -> String {
4+
if func_name == "main" || matches!(vis, AccessSpecifier::Extern | AccessSpecifier::PublicExtern) {
5+
func_name
6+
} else {
7+
format!("{}.{}", module_name, func_name)
8+
}
39
}
410

5-
pub(crate) fn make_global_var_abi_name(module_name: String, global_var_name: String) -> String {
6-
format!("{}.{}", module_name, global_var_name)
11+
pub(crate) fn make_global_var_abi_name(module_name: String, global_var_name: String, vis: AccessSpecifier) -> String {
12+
if matches!(vis, AccessSpecifier::Extern | AccessSpecifier::PublicExtern) {
13+
global_var_name
14+
} else {
15+
format!("{}.{}", module_name, global_var_name)
16+
}
717
}

crates/codegen/src/builder/funcs.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ impl<'a> CodeGenBuilder<'a> {
106106
if func_name == "main" {
107107
Linkage::External
108108
} else {
109-
self.build_func_linkage(vis)
109+
self.build_func_linkage(vis.clone())
110110
}
111111
};
112112

@@ -117,7 +117,7 @@ impl<'a> CodeGenBuilder<'a> {
117117
func_name
118118
} else {
119119
let module_name = self.get_module_name(module_id.unwrap());
120-
make_func_abi_name(module_name, func_name)
120+
make_func_abi_name(module_name, func_name, vis)
121121
}
122122
};
123123

crates/codegen/src/builder/variables.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ impl<'a> CodeGenBuilder<'a> {
1818
.try_into()
1919
.unwrap();
2020
let module_name = self.get_module_name(global_var_sig.module_id);
21-
let abi_name = make_global_var_abi_name(module_name, global_var_sig.name);
21+
let abi_name = make_global_var_abi_name(module_name, global_var_sig.name, global_var_sig.vis.clone());
2222

2323
let llvmmodule = self.llvmmodule.borrow_mut();
24-
let global_value = llvmmodule.add_global(concrete_type, None, &abi_name);
24+
let global_value = match llvmmodule.get_global(&abi_name) {
25+
Some(global_value) => global_value,
26+
None => llvmmodule.add_global(concrete_type, None, &abi_name),
27+
};
2528
global_value.set_linkage(Linkage::External);
2629
drop(llvmmodule);
2730

@@ -46,7 +49,7 @@ impl<'a> CodeGenBuilder<'a> {
4649

4750
let global_var_type: BasicTypeEnum<'a> = global_var_type.unwrap().try_into().unwrap();
4851
let module_name = self.get_module_name(global_var.module_id);
49-
let abi_name = make_global_var_abi_name(module_name, global_var.name.clone());
52+
let abi_name = make_global_var_abi_name(module_name, global_var.name.clone(), global_var.vis.clone());
5053

5154
let llvmmodule = self.llvmmodule.borrow();
5255
let global_var_value = llvmmodule.add_global(global_var_type, None, &abi_name);
@@ -63,16 +66,22 @@ impl<'a> CodeGenBuilder<'a> {
6366
let global_value = local_ir_value.as_global_value().unwrap().0.clone();
6467
drop(irreg);
6568

69+
if let Some(concrete_type) = &global_var.ty {
70+
global_value.set_constant(concrete_type.is_const());
71+
}
72+
6673
if global_var.expr.is_some() {
6774
let lvalue = self.build_expr(None, global_var.expr.as_ref().unwrap());
6875
let rvalue = self.build_load_lvalue_to_rvalue(None, lvalue);
6976

7077
let basic_rvalue = rvalue.as_basic_value();
7178
global_value.set_initializer(&basic_rvalue);
72-
}
73-
74-
if let Some(concrete_type) = &global_var.ty {
75-
global_value.set_constant(concrete_type.is_const());
79+
} else {
80+
let basic_type: BasicTypeEnum<'a> = self
81+
.build_concrete_type(None, global_var.ty.clone().unwrap())
82+
.try_into()
83+
.unwrap();
84+
global_value.set_initializer(&basic_type.const_zero());
7685
}
7786

7887
self.insert_forward_decl_to_registry(

crates/resolver/src/scope.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,46 @@ impl LocalOrGlobalSymbol {
126126
LocalOrGlobalSymbol::GlobalSymbol(symbol_entry) => symbol_entry.get_symbol_id(),
127127
}
128128
}
129+
130+
pub fn as_struct(&self) -> Option<ResolvedStruct> {
131+
match self {
132+
LocalOrGlobalSymbol::LocalSymbol(local_symbol) => match &local_symbol.kind {
133+
LocalSymbolKind::Struct(resolved_struct) => Some(resolved_struct.clone()),
134+
_ => None,
135+
},
136+
LocalOrGlobalSymbol::GlobalSymbol(symbol_entry) => match &symbol_entry.kind {
137+
SymbolEntryKind::Struct(resolved_struct) => Some(resolved_struct.clone()),
138+
_ => None,
139+
},
140+
}
141+
}
142+
143+
pub fn as_enum(&self) -> Option<ResolvedEnum> {
144+
match self {
145+
LocalOrGlobalSymbol::LocalSymbol(local_symbol) => match &local_symbol.kind {
146+
LocalSymbolKind::Enum(resolved_enum) => Some(resolved_enum.clone()),
147+
_ => None,
148+
},
149+
LocalOrGlobalSymbol::GlobalSymbol(symbol_entry) => match &symbol_entry.kind {
150+
SymbolEntryKind::Enum(resolved_enum) => Some(resolved_enum.clone()),
151+
_ => None,
152+
},
153+
}
154+
}
155+
156+
pub fn as_global_var(&self) -> Option<ResolvedGlobalVar> {
157+
match self {
158+
LocalOrGlobalSymbol::LocalSymbol(..) => None,
159+
LocalOrGlobalSymbol::GlobalSymbol(symbol_entry) => symbol_entry.as_global_var().cloned(),
160+
}
161+
}
162+
163+
pub fn as_variable(&self) -> Option<ResolvedVariable> {
164+
match self {
165+
LocalOrGlobalSymbol::LocalSymbol(local_symbol) => local_symbol.as_variable().cloned(),
166+
LocalOrGlobalSymbol::GlobalSymbol(..) => None,
167+
}
168+
}
129169
}
130170

131171
impl LocalSymbol {

crates/static_analyzer/src/context.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ enum ControlContext {
2424
Switch(TypedSwitch),
2525
}
2626

27+
#[macro_export]
2728
macro_rules! update_global_symbol_type {
28-
($self:expr, $symbol_id:expr, $pattern:pat => $var:ident, $body:block) => {{
29+
($self:expr, $module_id:expr, $symbol_id:expr, $pattern:pat => $var:ident, $body:block) => {{
2930
let mut global_symbols = $self.resolver.global_symbols.lock().unwrap();
30-
let symbol_table = global_symbols.get_mut(&$self.module_id).unwrap();
31+
let symbol_table = global_symbols.get_mut(&$module_id).unwrap();
3132
match &mut symbol_table.entries.get_mut(&$symbol_id).unwrap().kind {
3233
$pattern => {
3334
let $var = $var;
@@ -138,7 +139,7 @@ impl<'a> AnalysisContext<'a> {
138139
TypedStatement::Interface(typed_interface) => self.analyze_interface(typed_interface),
139140
TypedStatement::Struct(typed_struct) => self.analyze_struct(typed_struct, false),
140141
TypedStatement::Enum(typed_enum) => self.analyze_enum(typed_enum, false),
141-
TypedStatement::Typedef(typed_typedef) => self.analyze_typedef(None, typed_typedef, false),
142+
TypedStatement::Typedef(typed_typedef) => self.analyze_typedef(None, typed_typedef),
142143
// Not analyzed
143144
TypedStatement::Import(_) => continue,
144145
// Invalid top-level statements
@@ -220,7 +221,7 @@ impl<'a> AnalysisContext<'a> {
220221
FlowState::Reachable
221222
}
222223
TypedStatement::Typedef(typed_typedef) => {
223-
self.analyze_typedef(Some(block_stmt.scope_id), typed_typedef, false);
224+
self.analyze_typedef(Some(block_stmt.scope_id), typed_typedef);
224225
FlowState::Reachable
225226
}
226227
// Invalid statements
@@ -277,7 +278,12 @@ impl<'a> AnalysisContext<'a> {
277278
}
278279
}
279280

280-
fn analyze_if_stmt(&mut self, scope_id: ScopeID, typed_if: &mut TypedIf, expected_type:Option<ConcreteType>) -> FlowState {
281+
fn analyze_if_stmt(
282+
&mut self,
283+
scope_id: ScopeID,
284+
typed_if: &mut TypedIf,
285+
expected_type: Option<ConcreteType>,
286+
) -> FlowState {
281287
let consequent_state = self.analyze_block_statement(&mut typed_if.consequent);
282288

283289
self.analyze_typed_expr_type(Some(scope_id), &mut typed_if.condition, expected_type.clone());
@@ -507,7 +513,7 @@ impl<'a> AnalysisContext<'a> {
507513
);
508514
}
509515

510-
update_global_symbol_type!(self, typed_global_var.symbol_id,
516+
update_global_symbol_type!(self, typed_global_var.module_id, typed_global_var.symbol_id,
511517
SymbolEntryKind::GlobalVar(resolved_var) => resolved_var, {
512518
resolved_var.global_var_sig.ty = typed_global_var.ty.clone();
513519
}
@@ -998,8 +1004,7 @@ impl<'a> AnalysisContext<'a> {
9981004
}
9991005
}
10001006

1001-
fn analyze_typedef(&mut self, scope_id_opt: Option<ScopeID>, typed_typedef: &mut TypedTypedef, is_local: bool) {
1002-
self.check_typedef_name(typed_typedef.name.clone(), typed_typedef.loc.clone(), is_local);
1007+
fn analyze_typedef(&mut self, scope_id_opt: Option<ScopeID>, typed_typedef: &mut TypedTypedef) {
10031008
typed_typedef.ty = match self.normalize_type(scope_id_opt, typed_typedef.ty.clone(), typed_typedef.loc.clone())
10041009
{
10051010
Some(concrete_type) => concrete_type,

crates/static_analyzer/src/diagnostics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ pub enum AnalyzerDiagKind {
55
ObjectNotSupportsMethods,
66
ObjectNotSupportsFields,
77
InvalidFatArrow,
8+
UseFatArrow,
89
StructMethodNotDefined {
910
struct_name: String,
1011
method_name: String,
@@ -142,6 +143,9 @@ pub enum AnalyzerDiagKind {
142143
impl fmt::Display for AnalyzerDiagKind {
143144
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144145
match self {
146+
AnalyzerDiagKind::UseFatArrow => {
147+
write!(f, "Use '->' instead of '.' when accessing a member via a pointer.")
148+
}
145149
AnalyzerDiagKind::InvalidUsageOfTheConcreteType => {
146150
write!(f, "Invalid usage of the concrete type.")
147151
}

crates/static_analyzer/src/naming.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ use diagcentral::{Diag, DiagLevel, DiagLoc};
55
enum NamingConvDeclKind {
66
Struct,
77
Enum,
8-
Typedef,
98
Interface,
109
}
1110

@@ -21,7 +20,6 @@ impl<'a> AnalysisContext<'a> {
2120
let kind_str = match decl_kind {
2221
NamingConvDeclKind::Struct => "Struct",
2322
NamingConvDeclKind::Enum => "Enum",
24-
NamingConvDeclKind::Typedef => "Typedef",
2523
NamingConvDeclKind::Interface => "Interface",
2624
};
2725

@@ -37,10 +35,6 @@ impl<'a> AnalysisContext<'a> {
3735
self.check_name(NamingConvDeclKind::Enum, &name, loc, is_local);
3836
}
3937

40-
pub(crate) fn check_typedef_name(&mut self, name: String, loc: Location, is_local: bool) {
41-
self.check_name(NamingConvDeclKind::Typedef, &name, loc, is_local);
42-
}
43-
4438
pub(crate) fn check_interface_name(&mut self, name: String, loc: Location, is_local: bool) {
4539
self.check_name(NamingConvDeclKind::Interface, &name, loc, is_local);
4640
}

0 commit comments

Comments
 (0)