From 7b767718432b3ca0855e285ea919b966d69e0dd8 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Sat, 11 Jul 2026 14:37:29 -0500 Subject: [PATCH] Repl with expressions working, let statements still not working. --- dm/src/main.rs | 4 +- dm/src/repl.rs | 126 ++++++++++++++++++++- dmc-lib/src/ir/ir_allocate.rs | 1 + dmc-lib/src/ir/ir_assign.rs | 1 + dmc-lib/src/ir/ir_binary_operation.rs | 2 + dmc-lib/src/ir/ir_block.rs | 1 + dmc-lib/src/ir/ir_call.rs | 1 + dmc-lib/src/ir/ir_expression.rs | 1 + dmc-lib/src/ir/ir_function.rs | 1 + dmc-lib/src/ir/ir_get_field_ref.rs | 1 + dmc-lib/src/ir/ir_get_field_ref_mut.rs | 1 + dmc-lib/src/ir/ir_operation.rs | 1 + dmc-lib/src/ir/ir_parameter.rs | 1 + dmc-lib/src/ir/ir_read_field.rs | 1 + dmc-lib/src/ir/ir_return.rs | 1 + dmc-lib/src/ir/ir_set_field.rs | 1 + dmc-lib/src/ir/ir_statement.rs | 1 + dmc-lib/src/ir/ir_variable.rs | 1 + dmc-lib/src/lowering/mod.rs | 3 + dmc-lib/src/semantic_analysis/mod.rs | 14 ++- dmc-lib/src/semantic_analysis/symbol.rs | 4 + dmc-lib/src/semantic_analysis/type_info.rs | 4 +- 22 files changed, 163 insertions(+), 9 deletions(-) diff --git a/dm/src/main.rs b/dm/src/main.rs index c99038c..be6bc34 100644 --- a/dm/src/main.rs +++ b/dm/src/main.rs @@ -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); } } } diff --git a/dm/src/repl.rs b/dm/src/repl.rs index ac12223..41b19e7 100644 --- a/dm/src/repl.rs +++ b/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 = None; - let fqn: Rc = 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 = 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, + variable_locations: &mut VariableLocations, + register_count: usize, + constants_table: &mut ConstantsTable, +) -> Result { + 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, + ) +} diff --git a/dmc-lib/src/ir/ir_allocate.rs b/dmc-lib/src/ir/ir_allocate.rs index 0d91666..3d02c12 100644 --- a/dmc-lib/src/ir/ir_allocate.rs +++ b/dmc-lib/src/ir/ir_allocate.rs @@ -1,6 +1,7 @@ use std::fmt::{Display, Formatter}; use std::rc::Rc; +#[derive(Debug)] pub struct IrAllocate { class_fqn: Rc, } diff --git a/dmc-lib/src/ir/ir_assign.rs b/dmc-lib/src/ir/ir_assign.rs index 70ee32e..cf7c781 100644 --- a/dmc-lib/src/ir/ir_assign.rs +++ b/dmc-lib/src/ir/ir_assign.rs @@ -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, diff --git a/dmc-lib/src/ir/ir_binary_operation.rs b/dmc-lib/src/ir/ir_binary_operation.rs index e1618e8..a4b33f1 100644 --- a/dmc-lib/src/ir/ir_binary_operation.rs +++ b/dmc-lib/src/ir/ir_binary_operation.rs @@ -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, right: Box, diff --git a/dmc-lib/src/ir/ir_block.rs b/dmc-lib/src/ir/ir_block.rs index 911b0c8..ddc8a1d 100644 --- a/dmc-lib/src/ir/ir_block.rs +++ b/dmc-lib/src/ir/ir_block.rs @@ -5,6 +5,7 @@ use std::collections::HashSet; pub type IrBlockId = usize; +#[derive(Debug)] pub struct IrBlock { id: IrBlockId, debug_label: String, diff --git a/dmc-lib/src/ir/ir_call.rs b/dmc-lib/src/ir/ir_call.rs index 6b3f7c3..8d3d471 100644 --- a/dmc-lib/src/ir/ir_call.rs +++ b/dmc-lib/src/ir/ir_call.rs @@ -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, arguments: Vec, diff --git a/dmc-lib/src/ir/ir_expression.rs b/dmc-lib/src/ir/ir_expression.rs index b0b22e1..858a7a2 100644 --- a/dmc-lib/src/ir/ir_expression.rs +++ b/dmc-lib/src/ir/ir_expression.rs @@ -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), diff --git a/dmc-lib/src/ir/ir_function.rs b/dmc-lib/src/ir/ir_function.rs index b4e8852..973cc24 100644 --- a/dmc-lib/src/ir/ir_function.rs +++ b/dmc-lib/src/ir/ir_function.rs @@ -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, parameters: Vec, diff --git a/dmc-lib/src/ir/ir_get_field_ref.rs b/dmc-lib/src/ir/ir_get_field_ref.rs index 7d84926..b54e489 100644 --- a/dmc-lib/src/ir/ir_get_field_ref.rs +++ b/dmc-lib/src/ir/ir_get_field_ref.rs @@ -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, diff --git a/dmc-lib/src/ir/ir_get_field_ref_mut.rs b/dmc-lib/src/ir/ir_get_field_ref_mut.rs index da47e4f..6ded978 100644 --- a/dmc-lib/src/ir/ir_get_field_ref_mut.rs +++ b/dmc-lib/src/ir/ir_get_field_ref_mut.rs @@ -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, diff --git a/dmc-lib/src/ir/ir_operation.rs b/dmc-lib/src/ir/ir_operation.rs index e872716..aec6117 100644 --- a/dmc-lib/src/ir/ir_operation.rs +++ b/dmc-lib/src/ir/ir_operation.rs @@ -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), diff --git a/dmc-lib/src/ir/ir_parameter.rs b/dmc-lib/src/ir/ir_parameter.rs index c26d1ce..4298682 100644 --- a/dmc-lib/src/ir/ir_parameter.rs +++ b/dmc-lib/src/ir/ir_parameter.rs @@ -5,6 +5,7 @@ use std::rc::Rc; pub type IrParameterId = usize; +#[derive(Debug)] pub struct IrParameter { name: Rc, type_info: IrTypeInfo, diff --git a/dmc-lib/src/ir/ir_read_field.rs b/dmc-lib/src/ir/ir_read_field.rs index 7390b9a..107f437 100644 --- a/dmc-lib/src/ir/ir_read_field.rs +++ b/dmc-lib/src/ir/ir_read_field.rs @@ -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, } diff --git a/dmc-lib/src/ir/ir_return.rs b/dmc-lib/src/ir/ir_return.rs index 4bd786b..d858e85 100644 --- a/dmc-lib/src/ir/ir_return.rs +++ b/dmc-lib/src/ir/ir_return.rs @@ -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, } diff --git a/dmc-lib/src/ir/ir_set_field.rs b/dmc-lib/src/ir/ir_set_field.rs index af3148f..ebc5e46 100644 --- a/dmc-lib/src/ir/ir_set_field.rs +++ b/dmc-lib/src/ir/ir_set_field.rs @@ -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, diff --git a/dmc-lib/src/ir/ir_statement.rs b/dmc-lib/src/ir/ir_statement.rs index 383d0d5..9100512 100644 --- a/dmc-lib/src/ir/ir_statement.rs +++ b/dmc-lib/src/ir/ir_statement.rs @@ -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), diff --git a/dmc-lib/src/ir/ir_variable.rs b/dmc-lib/src/ir/ir_variable.rs index fe29b2e..ec042b3 100644 --- a/dmc-lib/src/ir/ir_variable.rs +++ b/dmc-lib/src/ir/ir_variable.rs @@ -4,6 +4,7 @@ use std::rc::Rc; pub type IrVariableId = usize; +#[derive(Debug)] pub struct IrVariable { name: Rc, type_info: IrTypeInfo, diff --git a/dmc-lib/src/lowering/mod.rs b/dmc-lib/src/lowering/mod.rs index bc5c0d1..ebaa95b 100644 --- a/dmc-lib/src/lowering/mod.rs +++ b/dmc-lib/src/lowering/mod.rs @@ -34,6 +34,7 @@ pub struct LowerToIrResult { pub functions: Vec, } +#[derive(Debug)] struct LowerToIrContext<'a> { symbols: &'a [Symbol], nodes_to_symbols: &'a HashMap, @@ -104,6 +105,7 @@ pub fn lower_to_ir_synthetic_function( ) } +#[derive(Debug)] struct LowerToIrFunctionContext { blocks: Vec, ir_variables: Vec, @@ -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 diff --git a/dmc-lib/src/semantic_analysis/mod.rs b/dmc-lib/src/semantic_analysis/mod.rs index e6935fa..773179c 100644 --- a/dmc-lib/src/semantic_analysis/mod.rs +++ b/dmc-lib/src/semantic_analysis/mod.rs @@ -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 { + &mut self.scopes + } + pub fn symbols(&self) -> &[Symbol] { &self.symbols } diff --git a/dmc-lib/src/semantic_analysis/symbol.rs b/dmc-lib/src/semantic_analysis/symbol.rs index 4b97de9..5f994d9 100644 --- a/dmc-lib/src/semantic_analysis/symbol.rs +++ b/dmc-lib/src/semantic_analysis/symbol.rs @@ -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, declared_name_source_range: Option, @@ -82,6 +84,7 @@ impl FunctionSymbol { } } +#[derive(Debug)] pub struct ParameterSymbol { name: Rc, source_range: Option, @@ -105,6 +108,7 @@ impl ParameterSymbol { } } +#[derive(Debug)] pub struct VariableSymbol { name: Rc, source_range: Option, diff --git a/dmc-lib/src/semantic_analysis/type_info.rs b/dmc-lib/src/semantic_analysis/type_info.rs index dbaaeb7..e025d09 100644 --- a/dmc-lib/src/semantic_analysis/type_info.rs +++ b/dmc-lib/src/semantic_analysis/type_info.rs @@ -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, return_type_info_id: TypeInfoId,