Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions rusty_basic/src/bin/rusty_basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::fs::File;

use rusty_basic::instruction_generator::{generate_instructions, unwrap_linter_context};
use rusty_basic::interpreter::{InterpreterTrait, new_default_interpreter};
use rusty_linter::{Context, lint};
use rusty_linter::core::{LinterContext, lint};
use rusty_parser::{Program, parse_main_file};

fn main() {
Expand Down Expand Up @@ -33,7 +33,7 @@ fn on_parsed(program: Program, run_options: RunOptions) {
}
}

fn on_linted(program: Program, linter_context: Context, run_options: RunOptions) {
fn on_linted(program: Program, linter_context: LinterContext, run_options: RunOptions) {
let (linter_names, user_defined_types) = unwrap_linter_context(linter_context);
let instruction_generator_result = generate_instructions(program, linter_names);
let mut interpreter = new_default_interpreter(user_defined_types);
Expand Down
28 changes: 14 additions & 14 deletions rusty_basic/src/instruction_generator/calls.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rusty_common::{AtPos, Position, Positioned};
use rusty_linter::SubprogramName;
use rusty_linter::core::ScopeName;
use rusty_parser::*;

use crate::instruction_generator::{AddressOrLabel, Instruction, InstructionGenerator};
Expand Down Expand Up @@ -42,18 +42,18 @@ impl InstructionGenerator {
) {
let Positioned { element: name, pos } = function_name;
let qualified_name = name.demand_qualified();
let subprogram_name = SubprogramName::Function(qualified_name.clone());
let scope_name = ScopeName::Function(qualified_name.clone());
// cloning to fight the borrow checker
let function_parameters: Vec<Parameter> = self
.subprogram_info_repository
.get_subprogram_info(&subprogram_name)
.get_subprogram_info(&scope_name)
.params
.clone();
self.generate_push_named_args_instructions(&function_parameters, &args, pos);
self.push_stack(subprogram_name.clone(), pos);
self.push_stack(scope_name.clone(), pos);
let index = self.instructions.len();
self.push(Instruction::PushRet(index + 2), pos);
self.jump_to_subprogram(&subprogram_name, pos);
self.jump_to_subprogram(&scope_name, pos);
// TODO find different way for by ref args
// stash by-ref variables
self.generate_stash_by_ref_args(&args);
Expand All @@ -69,18 +69,18 @@ impl InstructionGenerator {

pub fn generate_sub_call_instructions(&mut self, sub_call: SubCall, pos: Position) {
let (name, args) = sub_call.into();
let subprogram_name = SubprogramName::Sub(name);
let scope_name = ScopeName::Sub(name);
// cloning to fight the borrow checker
let sub_impl_parameters: Vec<Parameter> = self
.subprogram_info_repository
.get_subprogram_info(&subprogram_name)
.get_subprogram_info(&scope_name)
.params
.clone();
self.generate_push_named_args_instructions(&sub_impl_parameters, &args, pos);
self.push_stack(subprogram_name.clone(), pos);
self.push_stack(scope_name.clone(), pos);
let index = self.instructions.len();
self.push(Instruction::PushRet(index + 2), pos); // points to "generate_stash_by_ref_args"
self.jump_to_subprogram(&subprogram_name, pos);
self.jump_to_subprogram(&scope_name, pos);
self.generate_stash_by_ref_args(&args);
self.push(Instruction::PopStack, pos);
self.generate_un_stash_by_ref_args(&args);
Expand Down Expand Up @@ -148,20 +148,20 @@ impl InstructionGenerator {
}
}

fn push_stack(&mut self, subprogram_name: SubprogramName, pos: Position) {
fn push_stack(&mut self, scope_name: ScopeName, pos: Position) {
if self
.subprogram_info_repository
.get_subprogram_info(&subprogram_name)
.get_subprogram_info(&scope_name)
.is_static
{
self.push(Instruction::PushStaticStack(subprogram_name), pos);
self.push(Instruction::PushStaticStack(scope_name), pos);
} else {
self.push(Instruction::PushStack, pos);
}
}

fn jump_to_subprogram(&mut self, subprogram_name: &SubprogramName, pos: Position) {
let label: BareName = Self::format_subprogram_label(subprogram_name);
fn jump_to_subprogram(&mut self, scope_name: &ScopeName, pos: Position) {
let label: BareName = Self::format_subprogram_label(scope_name);
self.push(Instruction::Jump(AddressOrLabel::Unresolved(label)), pos);
}
}
14 changes: 7 additions & 7 deletions rusty_basic/src/instruction_generator/dim.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rusty_common::*;
use rusty_linter::core::ScopeName;
use rusty_parser::*;
use rusty_variant::Variant;

Expand Down Expand Up @@ -45,13 +46,12 @@ impl InstructionGenerator {

impl InstructionGenerator {
fn is_in_static_subprogram(&self) -> bool {
match &self.current_subprogram {
Some(subprogram_name) => {
self.subprogram_info_repository
.get_subprogram_info(subprogram_name)
.is_static
}
_ => false,
if self.current_subprogram == ScopeName::Global {
false
} else {
self.subprogram_info_repository
.get_subprogram_info(&self.current_subprogram)
.is_static
}
}

Expand Down
1 change: 1 addition & 0 deletions rusty_basic/src/instruction_generator/expression.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use rusty_common::*;
use rusty_linter::core::VariableInfo;
use rusty_parser::*;
use rusty_variant::Variant;

Expand Down
41 changes: 24 additions & 17 deletions rusty_basic/src/instruction_generator/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rusty_common::{AtPos, CaseInsensitiveString, Position, Positioned};
use rusty_linter::{Context, Names, SubprogramName};
use rusty_linter::core::{LinterContext, ScopeName};
use rusty_linter::names::Names;
use rusty_parser::{
Assignment, BareName, BuiltInFunction, BuiltInSub, DimVar, Expression, ExpressionType, FileHandle, FunctionImplementation, GlobalStatement, HasExpressionType, Name, Parameter, Program, Statement, Statements, SubImplementation, TypeQualifier, UserDefinedTypes
};
Expand All @@ -11,10 +12,8 @@ use crate::instruction_generator::subprogram_info::{
SubprogramInfoCollector, SubprogramInfoRepository
};

pub fn unwrap_linter_context(linter_context: Context) -> (Names, UserDefinedTypes) {
let (pre_linter_result, linter_names) = linter_context.into();
let user_defined_types = pre_linter_result.into();
(linter_names, user_defined_types)
pub fn unwrap_linter_context(linter_context: LinterContext) -> (Names, UserDefinedTypes) {
(linter_context.names, linter_context.user_defined_types)
}

/// Generates instructions for the given program.
Expand Down Expand Up @@ -181,7 +180,7 @@ pub enum Instruction {
PushUnnamedByRef,

PushStack,
PushStaticStack(SubprogramName),
PushStaticStack(ScopeName),
PopStack,

EnqueueToReturnStack(usize),
Expand Down Expand Up @@ -264,7 +263,7 @@ pub struct InstructionGenerator {
pub instructions: Vec<InstructionPos>,
pub statement_addresses: Vec<usize>,
pub subprogram_info_repository: SubprogramInfoRepository,
pub current_subprogram: Option<SubprogramName>,
pub current_subprogram: ScopeName,
pub linter_names: Names,
}

Expand All @@ -274,7 +273,7 @@ impl InstructionGenerator {
instructions: vec![],
statement_addresses: vec![],
subprogram_info_repository,
current_subprogram: None,
current_subprogram: ScopeName::Global,
linter_names,
}
}
Expand Down Expand Up @@ -375,7 +374,7 @@ impl InstructionGenerator {
let qualifier = function_name
.qualifier()
.expect("Expected qualified function name");
self.mark_current_subprogram(SubprogramName::Function(function_name), pos);
self.mark_current_subprogram(ScopeName::Function(function_name), pos);
// set default value
self.push(Instruction::AllocateBuiltIn(qualifier), pos);
self.subprogram_body(body, pos);
Expand All @@ -397,16 +396,21 @@ impl InstructionGenerator {
body,
..
} = sub_implementation;
self.mark_current_subprogram(SubprogramName::Sub(name), pos);
self.mark_current_subprogram(ScopeName::Sub(name), pos);
self.subprogram_body(body, pos);
}

fn mark_current_subprogram(&mut self, subprogram_name: SubprogramName, pos: Position) {
fn mark_current_subprogram(&mut self, scope_name: ScopeName, pos: Position) {
debug_assert_ne!(
scope_name,
ScopeName::Global,
"should not mark global scope"
);
self.push(
Instruction::Label(Self::format_subprogram_label(&subprogram_name)),
Instruction::Label(Self::format_subprogram_label(&scope_name)),
pos,
);
self.current_subprogram = Some(subprogram_name);
self.current_subprogram = scope_name;
}

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

pub fn format_subprogram_label(subprogram_name: &SubprogramName) -> BareName {
let s: String = match subprogram_name {
SubprogramName::Function(function_name) => {
pub fn format_subprogram_label(scope_name: &ScopeName) -> BareName {
let s: String = match scope_name {
ScopeName::Function(function_name) => {
let mut s: String = String::new();
s.push_str(":fun:");
s.push_str(&function_name.to_string());
s
}
SubprogramName::Sub(sub_name) => {
ScopeName::Sub(sub_name) => {
let mut s: String = String::new();
s.push_str(":sub:");
s.push_str(sub_name.as_ref());
s
}
ScopeName::Global => {
panic!("Should not generate label for global scope")
}
};
BareName::new(s)
}
Expand Down
22 changes: 10 additions & 12 deletions rusty_basic/src/instruction_generator/subprogram_info.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;

use rusty_common::Positioned;
use rusty_linter::SubprogramName;
use rusty_linter::core::ScopeName;
use rusty_parser::*;

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

#[derive(Default)]
pub struct SubprogramInfoCollector {
map: HashMap<SubprogramName, SubprogramInfo>,
map: HashMap<ScopeName, SubprogramInfo>,
}

impl SubprogramInfoCollector {
Expand All @@ -51,30 +51,28 @@ impl SubprogramInfoCollector {

fn visit_function_implementation(&mut self, f: &FunctionImplementation) {
let function_name = f.name.element.clone().demand_qualified();
let subprogram_name = SubprogramName::Function(function_name);
self.map.insert(subprogram_name, SubprogramInfo::new(f));
let scope_name = ScopeName::Function(function_name);
self.map.insert(scope_name, SubprogramInfo::new(f));
}

fn visit_sub_implementation(&mut self, s: &SubImplementation) {
let sub_name = s.name.element.clone();
let subprogram_name = SubprogramName::Sub(sub_name);
self.map.insert(subprogram_name, SubprogramInfo::new(s));
let scope_name = ScopeName::Sub(sub_name);
self.map.insert(scope_name, SubprogramInfo::new(s));
}
}

pub struct SubprogramInfoRepository {
map: HashMap<SubprogramName, SubprogramInfo>,
map: HashMap<ScopeName, SubprogramInfo>,
}

impl SubprogramInfoRepository {
pub fn new(map: HashMap<SubprogramName, SubprogramInfo>) -> Self {
pub fn new(map: HashMap<ScopeName, SubprogramInfo>) -> Self {
Self { map }
}

pub fn get_subprogram_info(&self, subprogram_name: &SubprogramName) -> &SubprogramInfo {
self.map
.get(subprogram_name)
.expect("Function/Sub not found")
pub fn get_subprogram_info(&self, scope_name: &ScopeName) -> &SubprogramInfo {
self.map.get(scope_name).expect("Function/Sub not found")
}
}

Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/instruction_generator/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use rusty_common::NoPosContainer;
use rusty_linter::lint;
use rusty_linter::core::lint;
use rusty_parser::{UserDefinedTypes, parse};

use crate::instruction_generator::{
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/chr.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;
use rusty_parser::BuiltInFunction;

use crate::RuntimeError;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/color.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;

use crate::RuntimeError;
use crate::interpreter::interpreter_trait::InterpreterTrait;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/def_seg.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;

use crate::RuntimeError;
use crate::interpreter::interpreter_trait::InterpreterTrait;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::convert::TryFrom;

use rusty_linter::qualifier_of_variant;
use rusty_linter::core::qualifier_of_variant;
use rusty_parser::{FileHandle, TypeQualifier};
use rusty_variant::Variant;

Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/mkd.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;
use rusty_parser::BuiltInFunction;
use rusty_variant::f64_to_bytes;

Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/open.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;
use rusty_parser::{FileAccess, FileHandle, FileMode};
use rusty_variant::Variant;

Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/poke.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;

use super::peek::INDICATOR_KEYS_ADDRESS;
use crate::RuntimeError;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/read.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::{CastVariant, qualifier_of_variant};
use rusty_linter::core::{CastVariant, qualifier_of_variant};

use crate::RuntimeError;
use crate::interpreter::interpreter_trait::InterpreterTrait;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/space.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;
use rusty_parser::BuiltInFunction;

use crate::RuntimeError;
Expand Down
2 changes: 1 addition & 1 deletion rusty_basic/src/interpreter/built_ins/string_fn.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use rusty_linter::QBNumberCast;
use rusty_linter::core::QBNumberCast;
use rusty_parser::BuiltInFunction;
use rusty_variant::Variant;

Expand Down
Loading