Skip to content

Commit a8f0358

Browse files
authored
refactor(linter): Moved variable_info to linter (#123)
* Rename NameContext to NameScope Context is a rather overloaded and overused term. Scope is more appropriate here. * Converted Signature to an enum * Add Global enum member to SubprogramName * Rename SubprogramName to ScopeName, NameScope to ScopeKind * Removed traits HasSubprograms and HasUserDefinedTypes * Renamed `traits` modules * Move linter context into core module * Rename linter Context to LinterContext * Removed PreLinterResult * Do not use anonymous fields in names module * Rename "main" to "names_outer" * Moved variable_info from parser to linter * Re-organized linter modules, moved main lint function inside core module * Fixed clippy warning
1 parent f91df75 commit a8f0358

96 files changed

Lines changed: 612 additions & 796 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

rusty_basic/src/bin/rusty_basic.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::fs::File;
33

44
use rusty_basic::instruction_generator::{generate_instructions, unwrap_linter_context};
55
use rusty_basic::interpreter::{InterpreterTrait, new_default_interpreter};
6-
use rusty_linter::{Context, lint};
6+
use rusty_linter::core::{LinterContext, lint};
77
use rusty_parser::{Program, parse_main_file};
88

99
fn main() {
@@ -33,7 +33,7 @@ fn on_parsed(program: Program, run_options: RunOptions) {
3333
}
3434
}
3535

36-
fn on_linted(program: Program, linter_context: Context, run_options: RunOptions) {
36+
fn on_linted(program: Program, linter_context: LinterContext, run_options: RunOptions) {
3737
let (linter_names, user_defined_types) = unwrap_linter_context(linter_context);
3838
let instruction_generator_result = generate_instructions(program, linter_names);
3939
let mut interpreter = new_default_interpreter(user_defined_types);

rusty_basic/src/instruction_generator/calls.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rusty_common::{AtPos, Position, Positioned};
2-
use rusty_linter::SubprogramName;
2+
use rusty_linter::core::ScopeName;
33
use rusty_parser::*;
44

55
use crate::instruction_generator::{AddressOrLabel, Instruction, InstructionGenerator};
@@ -42,18 +42,18 @@ impl InstructionGenerator {
4242
) {
4343
let Positioned { element: name, pos } = function_name;
4444
let qualified_name = name.demand_qualified();
45-
let subprogram_name = SubprogramName::Function(qualified_name.clone());
45+
let scope_name = ScopeName::Function(qualified_name.clone());
4646
// cloning to fight the borrow checker
4747
let function_parameters: Vec<Parameter> = self
4848
.subprogram_info_repository
49-
.get_subprogram_info(&subprogram_name)
49+
.get_subprogram_info(&scope_name)
5050
.params
5151
.clone();
5252
self.generate_push_named_args_instructions(&function_parameters, &args, pos);
53-
self.push_stack(subprogram_name.clone(), pos);
53+
self.push_stack(scope_name.clone(), pos);
5454
let index = self.instructions.len();
5555
self.push(Instruction::PushRet(index + 2), pos);
56-
self.jump_to_subprogram(&subprogram_name, pos);
56+
self.jump_to_subprogram(&scope_name, pos);
5757
// TODO find different way for by ref args
5858
// stash by-ref variables
5959
self.generate_stash_by_ref_args(&args);
@@ -69,18 +69,18 @@ impl InstructionGenerator {
6969

7070
pub fn generate_sub_call_instructions(&mut self, sub_call: SubCall, pos: Position) {
7171
let (name, args) = sub_call.into();
72-
let subprogram_name = SubprogramName::Sub(name);
72+
let scope_name = ScopeName::Sub(name);
7373
// cloning to fight the borrow checker
7474
let sub_impl_parameters: Vec<Parameter> = self
7575
.subprogram_info_repository
76-
.get_subprogram_info(&subprogram_name)
76+
.get_subprogram_info(&scope_name)
7777
.params
7878
.clone();
7979
self.generate_push_named_args_instructions(&sub_impl_parameters, &args, pos);
80-
self.push_stack(subprogram_name.clone(), pos);
80+
self.push_stack(scope_name.clone(), pos);
8181
let index = self.instructions.len();
8282
self.push(Instruction::PushRet(index + 2), pos); // points to "generate_stash_by_ref_args"
83-
self.jump_to_subprogram(&subprogram_name, pos);
83+
self.jump_to_subprogram(&scope_name, pos);
8484
self.generate_stash_by_ref_args(&args);
8585
self.push(Instruction::PopStack, pos);
8686
self.generate_un_stash_by_ref_args(&args);
@@ -148,20 +148,20 @@ impl InstructionGenerator {
148148
}
149149
}
150150

151-
fn push_stack(&mut self, subprogram_name: SubprogramName, pos: Position) {
151+
fn push_stack(&mut self, scope_name: ScopeName, pos: Position) {
152152
if self
153153
.subprogram_info_repository
154-
.get_subprogram_info(&subprogram_name)
154+
.get_subprogram_info(&scope_name)
155155
.is_static
156156
{
157-
self.push(Instruction::PushStaticStack(subprogram_name), pos);
157+
self.push(Instruction::PushStaticStack(scope_name), pos);
158158
} else {
159159
self.push(Instruction::PushStack, pos);
160160
}
161161
}
162162

163-
fn jump_to_subprogram(&mut self, subprogram_name: &SubprogramName, pos: Position) {
164-
let label: BareName = Self::format_subprogram_label(subprogram_name);
163+
fn jump_to_subprogram(&mut self, scope_name: &ScopeName, pos: Position) {
164+
let label: BareName = Self::format_subprogram_label(scope_name);
165165
self.push(Instruction::Jump(AddressOrLabel::Unresolved(label)), pos);
166166
}
167167
}

rusty_basic/src/instruction_generator/dim.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rusty_common::*;
2+
use rusty_linter::core::ScopeName;
23
use rusty_parser::*;
34
use rusty_variant::Variant;
45

@@ -45,13 +46,12 @@ impl InstructionGenerator {
4546

4647
impl InstructionGenerator {
4748
fn is_in_static_subprogram(&self) -> bool {
48-
match &self.current_subprogram {
49-
Some(subprogram_name) => {
50-
self.subprogram_info_repository
51-
.get_subprogram_info(subprogram_name)
52-
.is_static
53-
}
54-
_ => false,
49+
if self.current_subprogram == ScopeName::Global {
50+
false
51+
} else {
52+
self.subprogram_info_repository
53+
.get_subprogram_info(&self.current_subprogram)
54+
.is_static
5555
}
5656
}
5757

rusty_basic/src/instruction_generator/expression.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use rusty_common::*;
2+
use rusty_linter::core::VariableInfo;
23
use rusty_parser::*;
34
use rusty_variant::Variant;
45

rusty_basic/src/instruction_generator/main.rs

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use rusty_common::{AtPos, CaseInsensitiveString, Position, Positioned};
2-
use rusty_linter::{Context, Names, SubprogramName};
2+
use rusty_linter::core::{LinterContext, ScopeName};
3+
use rusty_linter::names::Names;
34
use rusty_parser::{
45
Assignment, BareName, BuiltInFunction, BuiltInSub, DimVar, Expression, ExpressionType, FileHandle, FunctionImplementation, GlobalStatement, HasExpressionType, Name, Parameter, Program, Statement, Statements, SubImplementation, TypeQualifier, UserDefinedTypes
56
};
@@ -11,10 +12,8 @@ use crate::instruction_generator::subprogram_info::{
1112
SubprogramInfoCollector, SubprogramInfoRepository
1213
};
1314

14-
pub fn unwrap_linter_context(linter_context: Context) -> (Names, UserDefinedTypes) {
15-
let (pre_linter_result, linter_names) = linter_context.into();
16-
let user_defined_types = pre_linter_result.into();
17-
(linter_names, user_defined_types)
15+
pub fn unwrap_linter_context(linter_context: LinterContext) -> (Names, UserDefinedTypes) {
16+
(linter_context.names, linter_context.user_defined_types)
1817
}
1918

2019
/// Generates instructions for the given program.
@@ -181,7 +180,7 @@ pub enum Instruction {
181180
PushUnnamedByRef,
182181

183182
PushStack,
184-
PushStaticStack(SubprogramName),
183+
PushStaticStack(ScopeName),
185184
PopStack,
186185

187186
EnqueueToReturnStack(usize),
@@ -264,7 +263,7 @@ pub struct InstructionGenerator {
264263
pub instructions: Vec<InstructionPos>,
265264
pub statement_addresses: Vec<usize>,
266265
pub subprogram_info_repository: SubprogramInfoRepository,
267-
pub current_subprogram: Option<SubprogramName>,
266+
pub current_subprogram: ScopeName,
268267
pub linter_names: Names,
269268
}
270269

@@ -274,7 +273,7 @@ impl InstructionGenerator {
274273
instructions: vec![],
275274
statement_addresses: vec![],
276275
subprogram_info_repository,
277-
current_subprogram: None,
276+
current_subprogram: ScopeName::Global,
278277
linter_names,
279278
}
280279
}
@@ -375,7 +374,7 @@ impl InstructionGenerator {
375374
let qualifier = function_name
376375
.qualifier()
377376
.expect("Expected qualified function name");
378-
self.mark_current_subprogram(SubprogramName::Function(function_name), pos);
377+
self.mark_current_subprogram(ScopeName::Function(function_name), pos);
379378
// set default value
380379
self.push(Instruction::AllocateBuiltIn(qualifier), pos);
381380
self.subprogram_body(body, pos);
@@ -397,16 +396,21 @@ impl InstructionGenerator {
397396
body,
398397
..
399398
} = sub_implementation;
400-
self.mark_current_subprogram(SubprogramName::Sub(name), pos);
399+
self.mark_current_subprogram(ScopeName::Sub(name), pos);
401400
self.subprogram_body(body, pos);
402401
}
403402

404-
fn mark_current_subprogram(&mut self, subprogram_name: SubprogramName, pos: Position) {
403+
fn mark_current_subprogram(&mut self, scope_name: ScopeName, pos: Position) {
404+
debug_assert_ne!(
405+
scope_name,
406+
ScopeName::Global,
407+
"should not mark global scope"
408+
);
405409
self.push(
406-
Instruction::Label(Self::format_subprogram_label(&subprogram_name)),
410+
Instruction::Label(Self::format_subprogram_label(&scope_name)),
407411
pos,
408412
);
409-
self.current_subprogram = Some(subprogram_name);
413+
self.current_subprogram = scope_name;
410414
}
411415

412416
fn subprogram_body(&mut self, block: Statements, pos: Position) {
@@ -469,20 +473,23 @@ impl InstructionGenerator {
469473
self.statement_addresses.push(self.instructions.len());
470474
}
471475

472-
pub fn format_subprogram_label(subprogram_name: &SubprogramName) -> BareName {
473-
let s: String = match subprogram_name {
474-
SubprogramName::Function(function_name) => {
476+
pub fn format_subprogram_label(scope_name: &ScopeName) -> BareName {
477+
let s: String = match scope_name {
478+
ScopeName::Function(function_name) => {
475479
let mut s: String = String::new();
476480
s.push_str(":fun:");
477481
s.push_str(&function_name.to_string());
478482
s
479483
}
480-
SubprogramName::Sub(sub_name) => {
484+
ScopeName::Sub(sub_name) => {
481485
let mut s: String = String::new();
482486
s.push_str(":sub:");
483487
s.push_str(sub_name.as_ref());
484488
s
485489
}
490+
ScopeName::Global => {
491+
panic!("Should not generate label for global scope")
492+
}
486493
};
487494
BareName::new(s)
488495
}

rusty_basic/src/instruction_generator/subprogram_info.rs

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::collections::HashMap;
22

33
use rusty_common::Positioned;
4-
use rusty_linter::SubprogramName;
4+
use rusty_linter::core::ScopeName;
55
use rusty_parser::*;
66

77
/// Holds information about a subprogram that is needed at runtime.
@@ -27,7 +27,7 @@ impl SubprogramInfo {
2727

2828
#[derive(Default)]
2929
pub struct SubprogramInfoCollector {
30-
map: HashMap<SubprogramName, SubprogramInfo>,
30+
map: HashMap<ScopeName, SubprogramInfo>,
3131
}
3232

3333
impl SubprogramInfoCollector {
@@ -51,30 +51,28 @@ impl SubprogramInfoCollector {
5151

5252
fn visit_function_implementation(&mut self, f: &FunctionImplementation) {
5353
let function_name = f.name.element.clone().demand_qualified();
54-
let subprogram_name = SubprogramName::Function(function_name);
55-
self.map.insert(subprogram_name, SubprogramInfo::new(f));
54+
let scope_name = ScopeName::Function(function_name);
55+
self.map.insert(scope_name, SubprogramInfo::new(f));
5656
}
5757

5858
fn visit_sub_implementation(&mut self, s: &SubImplementation) {
5959
let sub_name = s.name.element.clone();
60-
let subprogram_name = SubprogramName::Sub(sub_name);
61-
self.map.insert(subprogram_name, SubprogramInfo::new(s));
60+
let scope_name = ScopeName::Sub(sub_name);
61+
self.map.insert(scope_name, SubprogramInfo::new(s));
6262
}
6363
}
6464

6565
pub struct SubprogramInfoRepository {
66-
map: HashMap<SubprogramName, SubprogramInfo>,
66+
map: HashMap<ScopeName, SubprogramInfo>,
6767
}
6868

6969
impl SubprogramInfoRepository {
70-
pub fn new(map: HashMap<SubprogramName, SubprogramInfo>) -> Self {
70+
pub fn new(map: HashMap<ScopeName, SubprogramInfo>) -> Self {
7171
Self { map }
7272
}
7373

74-
pub fn get_subprogram_info(&self, subprogram_name: &SubprogramName) -> &SubprogramInfo {
75-
self.map
76-
.get(subprogram_name)
77-
.expect("Function/Sub not found")
74+
pub fn get_subprogram_info(&self, scope_name: &ScopeName) -> &SubprogramInfo {
75+
self.map.get(scope_name).expect("Function/Sub not found")
7876
}
7977
}
8078

rusty_basic/src/instruction_generator/test_utils.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use rusty_common::NoPosContainer;
2-
use rusty_linter::lint;
2+
use rusty_linter::core::lint;
33
use rusty_parser::{UserDefinedTypes, parse};
44

55
use crate::instruction_generator::{

rusty_basic/src/interpreter/built_ins/chr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rusty_linter::QBNumberCast;
1+
use rusty_linter::core::QBNumberCast;
22
use rusty_parser::BuiltInFunction;
33

44
use crate::RuntimeError;

rusty_basic/src/interpreter/built_ins/color.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rusty_linter::QBNumberCast;
1+
use rusty_linter::core::QBNumberCast;
22

33
use crate::RuntimeError;
44
use crate::interpreter::interpreter_trait::InterpreterTrait;

rusty_basic/src/interpreter/built_ins/def_seg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rusty_linter::QBNumberCast;
1+
use rusty_linter::core::QBNumberCast;
22

33
use crate::RuntimeError;
44
use crate::interpreter::interpreter_trait::InterpreterTrait;

0 commit comments

Comments
 (0)