Repl with expressions working, let statements still not working.
This commit is contained in:
parent
ed6f15a8a9
commit
7b76771843
@ -1,7 +1,7 @@
|
||||
mod repl;
|
||||
mod run;
|
||||
|
||||
use crate::repl::repl;
|
||||
use crate::repl::{repl, repl_2};
|
||||
use crate::run::compile_and_run_script;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::io;
|
||||
@ -44,7 +44,7 @@ fn main() {
|
||||
compile_and_run_script(script, *show_asm, *show_ir, register_count);
|
||||
}
|
||||
SubCommand::Repl => {
|
||||
repl(&mut io::stdin().lock(), register_count);
|
||||
repl_2(&mut io::stdin().lock(), register_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
126
dm/src/repl.rs
126
dm/src/repl.rs
@ -7,9 +7,9 @@ use dmc_lib::ir::ir_variable::IrVariable;
|
||||
use dmc_lib::ir::variable_locations::VariableLocations;
|
||||
use dmc_lib::lexer::Lexer;
|
||||
use dmc_lib::offset_counter::OffsetCounter;
|
||||
use dmc_lib::parser::parse_expression;
|
||||
use dmc_lib::parser::{parse_expression, parse_let_statement};
|
||||
use dmc_lib::semantic_analysis::AnalysisContext;
|
||||
use dmc_lib::semantic_analysis::scope::ScopeId;
|
||||
use dmc_lib::semantic_analysis::scope::{Scope, ScopeId};
|
||||
use dmc_lib::symbol::variable_symbol::VariableSymbol;
|
||||
use dmc_lib::symbol_table::SymbolTable;
|
||||
use dmc_lib::token::TokenKind;
|
||||
@ -310,8 +310,17 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
let mut buffer = String::new();
|
||||
|
||||
let mut analysis_context = AnalysisContext::new();
|
||||
let mut function_scope_id: Option<ScopeId> = None;
|
||||
let fqn: Rc<str> = Rc::from("repl");
|
||||
let root_scope_id = analysis_context.root_scope_id();
|
||||
analysis_context
|
||||
.scopes_mut()
|
||||
.push(Scope::new(Some(root_scope_id))); // function scope
|
||||
let function_scope_id = analysis_context.scopes().len() - 1;
|
||||
analysis_context
|
||||
.scopes_mut()
|
||||
.push(Scope::new(Some(function_scope_id))); // body scope
|
||||
let body_scope_id = analysis_context.scopes().len() - 1;
|
||||
|
||||
let fqn: Rc<str> = Rc::from("__repl");
|
||||
let mut variable_locations = VariableLocations::new();
|
||||
let mut constants_table = ConstantsTable::new();
|
||||
|
||||
@ -342,6 +351,91 @@ pub fn repl_2(read: &mut impl BufRead, register_count: usize) {
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
match first_token.kind() {
|
||||
TokenKind::Let => {
|
||||
let compile_result = compile_let_statement_2(
|
||||
input,
|
||||
&mut analysis_context,
|
||||
body_scope_id,
|
||||
&fqn,
|
||||
&mut variable_locations,
|
||||
register_count,
|
||||
&mut constants_table,
|
||||
);
|
||||
match compile_result {
|
||||
Ok(function) => {
|
||||
dvm_context
|
||||
.functions_mut()
|
||||
.insert(function.name_owned(), function);
|
||||
}
|
||||
Err(diagnostics) => {
|
||||
for diagnostic in diagnostics {
|
||||
eprintln!("{}", diagnostic.message());
|
||||
}
|
||||
buffer.clear();
|
||||
continue 'repl;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let compile_result = compile_expression_2(
|
||||
input,
|
||||
&mut analysis_context,
|
||||
body_scope_id,
|
||||
&fqn,
|
||||
&mut variable_locations,
|
||||
register_count,
|
||||
&mut constants_table,
|
||||
);
|
||||
match compile_result {
|
||||
Ok(function) => {
|
||||
dvm_context
|
||||
.functions_mut()
|
||||
.insert(function.name_owned(), function);
|
||||
}
|
||||
Err(diagnostics) => {
|
||||
for diagnostic in diagnostics {
|
||||
eprintln!("{}", diagnostic.message());
|
||||
}
|
||||
buffer.clear();
|
||||
continue 'repl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (name, content) in constants_table.string_constants() {
|
||||
dvm_context.constants_mut().insert(
|
||||
name.clone(),
|
||||
Constant::String(StringConstant::new(name, content)),
|
||||
);
|
||||
}
|
||||
|
||||
let mut call_stack = CallStack::new();
|
||||
prepare_for_instruction_loop(&dvm_context, "__repl", &mut call_stack, &[]);
|
||||
|
||||
// copy all old locals to current call frame's stack
|
||||
// this has to be done with indexing because the preparation above creates space for them
|
||||
for (i, operand) in repl_fn_stack_locals.iter().enumerate() {
|
||||
let target_index = call_stack.top().fp() + i;
|
||||
call_stack.top_mut().stack_mut()[target_index] = operand.clone();
|
||||
}
|
||||
|
||||
let result = loop_instructions(
|
||||
&dvm_context,
|
||||
&mut vec![Operand::Null; register_count],
|
||||
&mut call_stack,
|
||||
);
|
||||
|
||||
// copy the top frame's stack locals back to OUR stack locals for next iteration
|
||||
repl_fn_stack_locals = std::mem::take(call_stack.top_mut().stack_mut());
|
||||
|
||||
if let Some(value) = result {
|
||||
println!("{}", value);
|
||||
}
|
||||
|
||||
buffer.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@ -371,3 +465,27 @@ fn compile_expression_2(
|
||||
constants_table,
|
||||
)
|
||||
}
|
||||
|
||||
fn compile_let_statement_2(
|
||||
input: &str,
|
||||
analysis_context: &mut AnalysisContext,
|
||||
function_scope_id: ScopeId,
|
||||
fqn: &Rc<str>,
|
||||
variable_locations: &mut VariableLocations,
|
||||
register_count: usize,
|
||||
constants_table: &mut ConstantsTable,
|
||||
) -> Result<Function, Diagnostics> {
|
||||
let (maybe_let_statement, parse_diagnostics) = parse_let_statement(input);
|
||||
if !parse_diagnostics.is_empty() {
|
||||
return Err(parse_diagnostics);
|
||||
}
|
||||
compile_statement_to_synthetic_function(
|
||||
&Statement::Let(maybe_let_statement.unwrap()),
|
||||
analysis_context,
|
||||
function_scope_id,
|
||||
fqn.clone(),
|
||||
variable_locations,
|
||||
register_count,
|
||||
constants_table,
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrAllocate {
|
||||
class_fqn: Rc<str>,
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ use crate::ir::ir_variable::IrVariableId;
|
||||
use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrAssign {
|
||||
destination: IrVariableId,
|
||||
initializer: Box<IrOperation>,
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IrBinaryOperator {
|
||||
Multiply,
|
||||
Divide,
|
||||
@ -17,6 +18,7 @@ pub enum IrBinaryOperator {
|
||||
BitwiseOr,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrBinaryOperation {
|
||||
left: Box<IrExpression>,
|
||||
right: Box<IrExpression>,
|
||||
|
||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
||||
|
||||
pub type IrBlockId = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrBlock {
|
||||
id: IrBlockId,
|
||||
debug_label: String,
|
||||
|
||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrCall {
|
||||
function_name: Rc<str>,
|
||||
arguments: Vec<IrExpression>,
|
||||
|
||||
@ -5,6 +5,7 @@ use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IrExpression {
|
||||
Parameter(IrParameterId),
|
||||
Variable(IrVariableId),
|
||||
|
||||
@ -9,6 +9,7 @@ use dvm_lib::vm::function::Function;
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrFunction {
|
||||
fqn: Rc<str>,
|
||||
parameters: Vec<IrParameter>,
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrGetFieldRef {
|
||||
self_variable_or_parameter: IrParameterOrVariable,
|
||||
field_index: usize,
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrGetFieldRefMut {
|
||||
self_variable_or_parameter: IrParameterOrVariable,
|
||||
field_index: usize,
|
||||
|
||||
@ -10,6 +10,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IrOperation {
|
||||
GetFieldRef(IrGetFieldRef),
|
||||
GetFieldRefMut(IrGetFieldRefMut),
|
||||
|
||||
@ -5,6 +5,7 @@ use std::rc::Rc;
|
||||
|
||||
pub type IrParameterId = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrParameter {
|
||||
name: Rc<str>,
|
||||
type_info: IrTypeInfo,
|
||||
|
||||
@ -3,6 +3,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrReadField {
|
||||
field_ref_variable: IrVariableId,
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrReturn {
|
||||
value: Option<IrExpression>,
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrSetField {
|
||||
field_ref_variable: IrVariableId,
|
||||
initializer: Box<IrExpression>,
|
||||
|
||||
@ -6,6 +6,7 @@ use crate::ir::ir_variable::IrVariableId;
|
||||
use crate::ir::register_allocation::VrUser;
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IrStatement {
|
||||
Assign(IrAssign),
|
||||
Call(IrCall),
|
||||
|
||||
@ -4,6 +4,7 @@ use std::rc::Rc;
|
||||
|
||||
pub type IrVariableId = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IrVariable {
|
||||
name: Rc<str>,
|
||||
type_info: IrTypeInfo,
|
||||
|
||||
@ -34,6 +34,7 @@ pub struct LowerToIrResult {
|
||||
pub functions: Vec<IrFunction>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LowerToIrContext<'a> {
|
||||
symbols: &'a [Symbol],
|
||||
nodes_to_symbols: &'a HashMap<NodeId, SymbolId>,
|
||||
@ -104,6 +105,7 @@ pub fn lower_to_ir_synthetic_function(
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct LowerToIrFunctionContext {
|
||||
blocks: Vec<IrBlock>,
|
||||
ir_variables: Vec<IrVariable>,
|
||||
@ -463,6 +465,7 @@ fn lower_expression_to_ir_expression(
|
||||
{
|
||||
IrExpression::Parameter(*rhs_ir_parameter_id)
|
||||
} else {
|
||||
println!("Dump:\n{:#?}\n{:#?}", ctx, fn_ctx);
|
||||
panic!(
|
||||
"Could not find parameter or variable for symbol_id {}",
|
||||
rhs_symbol_id
|
||||
|
||||
@ -44,9 +44,9 @@ pub struct AnalysisContext {
|
||||
impl AnalysisContext {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
root_scope_id: 0, // pushed in vec! below
|
||||
scopes: vec![Scope::new(None)],
|
||||
nodes_to_scopes: HashMap::new(),
|
||||
root_scope_id: 0, // already pushed in vec! above
|
||||
symbols: Vec::new(),
|
||||
nodes_to_symbols: HashMap::new(),
|
||||
type_infos: Vec::new(),
|
||||
@ -55,6 +55,18 @@ impl AnalysisContext {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn root_scope_id(&self) -> ScopeId {
|
||||
self.root_scope_id
|
||||
}
|
||||
|
||||
pub fn scopes(&self) -> &[Scope] {
|
||||
&self.scopes
|
||||
}
|
||||
|
||||
pub fn scopes_mut(&mut self) -> &mut Vec<Scope> {
|
||||
&mut self.scopes
|
||||
}
|
||||
|
||||
pub fn symbols(&self) -> &[Symbol] {
|
||||
&self.symbols
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ use std::rc::Rc;
|
||||
|
||||
pub type SymbolId = usize;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Symbol {
|
||||
Function(FunctionSymbol),
|
||||
Parameter(ParameterSymbol),
|
||||
@ -35,6 +36,7 @@ impl Symbol {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FunctionSymbol {
|
||||
declared_name: Rc<str>,
|
||||
declared_name_source_range: Option<SourceRange>,
|
||||
@ -82,6 +84,7 @@ impl FunctionSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ParameterSymbol {
|
||||
name: Rc<str>,
|
||||
source_range: Option<SourceRange>,
|
||||
@ -105,6 +108,7 @@ impl ParameterSymbol {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VariableSymbol {
|
||||
name: Rc<str>,
|
||||
source_range: Option<SourceRange>,
|
||||
|
||||
@ -2,7 +2,7 @@ use std::fmt::{Display, Formatter};
|
||||
|
||||
pub type TypeInfoId = usize;
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TypeInfo {
|
||||
Any,
|
||||
Function(FunctionTypeInfo),
|
||||
@ -31,7 +31,7 @@ impl Display for TypeInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FunctionTypeInfo {
|
||||
parameter_type_info_ids: Vec<TypeInfoId>,
|
||||
return_type_info_id: TypeInfoId,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user