removed waring (have remaind dead code for future feature)
This commit is contained in:
@@ -10,6 +10,7 @@ end
|
|||||||
* Planning:
|
* Planning:
|
||||||
allora quello che devo fare è:
|
allora quello che devo fare è:
|
||||||
** TODO Controllare se ho finito la questione del retourn:labe
|
** TODO Controllare se ho finito la questione del retourn:labe
|
||||||
|
** TODO Complete the use os source slice inside parser (many node hase syntetic source slice or badly wrpapped)
|
||||||
** TODO implement struct:
|
** TODO implement struct:
|
||||||
#+begin_src rlox
|
#+begin_src rlox
|
||||||
Cosa :: struct{
|
Cosa :: struct{
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
|
||||||
|
Data :: struct {
|
||||||
|
number: Number,
|
||||||
|
string: String,
|
||||||
|
bool: Bool
|
||||||
|
};
|
||||||
|
|
||||||
|
Data.new :: fn(number: Number, string: String, bool: Bool) -> Self
|
||||||
|
do
|
||||||
|
return Self {
|
||||||
|
number: number,
|
||||||
|
string: string,
|
||||||
|
bool: bool
|
||||||
|
};
|
||||||
|
end;
|
||||||
|
|
||||||
|
Data.function :: fn(
|
||||||
|
self,
|
||||||
|
number: Number,
|
||||||
|
string: String,
|
||||||
|
bool: Bool,)
|
||||||
|
{number == 42} : Nil
|
||||||
|
do
|
||||||
|
self.number = number;
|
||||||
|
self.string = string;
|
||||||
|
self.bool = bool;
|
||||||
|
end;
|
||||||
@@ -3,7 +3,7 @@ use crate::{
|
|||||||
common::{
|
common::{
|
||||||
ast::{AstNode, Expr, NodeId},
|
ast::{AstNode, Expr, NodeId},
|
||||||
base_value::{BaseValue, NativeFunction, Number, Truthy},
|
base_value::{BaseValue, NativeFunction, Number, Truthy},
|
||||||
lox_result::{runtime_error, LoxError, LoxResult},
|
lox_result::{LoxError, LoxResult, runtime_error},
|
||||||
},
|
},
|
||||||
frontend::{source_registry::SourceSlice, tokens::TokenType},
|
frontend::{source_registry::SourceSlice, tokens::TokenType},
|
||||||
};
|
};
|
||||||
@@ -32,14 +32,14 @@ impl Interpreter {
|
|||||||
let mut env = EnvironmentStack::new();
|
let mut env = EnvironmentStack::new();
|
||||||
let _ = env.declare(
|
let _ = env.declare(
|
||||||
"clock".to_string(),
|
"clock".to_string(),
|
||||||
BaseValue::NativeFunction(NativeFunction::new(Vec::default(), |_args| {
|
BaseValue::NativeFunction(Box::new(NativeFunction::new(Vec::default(), |_args| {
|
||||||
BaseValue::Number(Number::U128(
|
BaseValue::Number(Number::U128(
|
||||||
std::time::SystemTime::now()
|
std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_millis(),
|
.as_millis(),
|
||||||
))
|
))
|
||||||
})),
|
}))),
|
||||||
);
|
);
|
||||||
Self {
|
Self {
|
||||||
enviorment: env,
|
enviorment: env,
|
||||||
|
|||||||
+16
-16
@@ -2,8 +2,9 @@ use core::fmt;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::ops::{Add, Div, Mul, Not, Rem, Sub};
|
use std::ops::{Add, Div, Mul, Not, Rem, Sub};
|
||||||
|
use std::ptr::fn_addr_eq;
|
||||||
|
|
||||||
use crate::common::lox_result::{runtime_error, LoxResult};
|
use crate::common::lox_result::{LoxResult, runtime_error};
|
||||||
use crate::common::types::Type;
|
use crate::common::types::Type;
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::environment::EnvironmentStack, common::ast::AstNode,
|
backend::environment::EnvironmentStack, common::ast::AstNode,
|
||||||
@@ -270,9 +271,9 @@ pub enum BaseValue {
|
|||||||
Number(Number),
|
Number(Number),
|
||||||
Boolean(bool),
|
Boolean(bool),
|
||||||
Nil,
|
Nil,
|
||||||
Function(LoxFunction),
|
Function(Box<LoxFunction>),
|
||||||
NativeFunction(NativeFunction),
|
NativeFunction(Box<NativeFunction>),
|
||||||
Struct(Struct),
|
Struct(Box<Struct>),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Dict {
|
struct Dict {
|
||||||
@@ -284,18 +285,12 @@ struct ReturnValue {
|
|||||||
value: Type,
|
value: Type,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReturnValue {
|
|
||||||
pub fn new(label: Vec<String>, value: Type) -> Self {
|
|
||||||
Self { label, value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BaseValue {
|
impl BaseValue {
|
||||||
pub fn is_callable(&self) -> bool {
|
pub fn is_callable(&self) -> bool {
|
||||||
match self {
|
matches!(
|
||||||
BaseValue::Function(..) | BaseValue::NativeFunction(..) => true,
|
self,
|
||||||
_ => false,
|
BaseValue::Function(..) | BaseValue::NativeFunction(..)
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,11 +345,16 @@ impl LoxFunction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct NativeFunction {
|
pub struct NativeFunction {
|
||||||
pub parameters: Vec<(String, Type)>,
|
pub parameters: Vec<(String, Type)>,
|
||||||
pub function: fn(&[BaseValue]) -> BaseValue,
|
pub function: fn(&[BaseValue]) -> BaseValue,
|
||||||
}
|
}
|
||||||
|
impl PartialEq for NativeFunction {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.parameters == other.parameters && fn_addr_eq(self.function, other.function)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl NativeFunction {
|
impl NativeFunction {
|
||||||
pub fn new(parameters: Vec<(String, Type)>, function: fn(&[BaseValue]) -> BaseValue) -> Self {
|
pub fn new(parameters: Vec<(String, Type)>, function: fn(&[BaseValue]) -> BaseValue) -> Self {
|
||||||
@@ -367,7 +367,7 @@ impl NativeFunction {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct Struct {
|
pub struct Struct {
|
||||||
pub fields: Vec<(String, BaseValue)>,
|
pub fields: Vec<(String, Type)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trait implementations for BaseValue
|
// Trait implementations for BaseValue
|
||||||
|
|||||||
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
use crate::common::base_value::{BaseValue, Number};
|
use crate::common::base_value::{BaseValue, Number};
|
||||||
use crate::common::lox_result::{lexical_error, LoxError, LoxResult};
|
use crate::common::lox_result::{LoxError, LoxResult, lexical_error};
|
||||||
use crate::frontend::source_registry::{SourceId, SourcePosition, SourceSlice};
|
use crate::frontend::source_registry::{SourceId, SourcePosition, SourceSlice};
|
||||||
use crate::frontend::tokens::{Token, TokenType};
|
use crate::frontend::tokens::{Token, TokenType};
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ impl Lexer {
|
|||||||
token_type,
|
token_type,
|
||||||
text,
|
text,
|
||||||
SourceSlice::from_positions(
|
SourceSlice::from_positions(
|
||||||
self.source_id.clone(),
|
self.source_id,
|
||||||
self.start_pos.clone(),
|
self.start_pos.clone(),
|
||||||
self.end_pos.clone(),
|
self.end_pos.clone(),
|
||||||
),
|
),
|
||||||
@@ -115,7 +115,7 @@ impl Lexer {
|
|||||||
text,
|
text,
|
||||||
Some(literal),
|
Some(literal),
|
||||||
SourceSlice::from_positions(
|
SourceSlice::from_positions(
|
||||||
self.source_id.clone(),
|
self.source_id,
|
||||||
self.start_pos.clone(),
|
self.start_pos.clone(),
|
||||||
self.end_pos.clone(),
|
self.end_pos.clone(),
|
||||||
),
|
),
|
||||||
@@ -174,7 +174,7 @@ impl Lexer {
|
|||||||
if self.is_at_end() {
|
if self.is_at_end() {
|
||||||
return lexical_error(
|
return lexical_error(
|
||||||
SourceSlice::from_positions(
|
SourceSlice::from_positions(
|
||||||
self.source_id.clone(),
|
self.source_id,
|
||||||
self.start_pos.clone(),
|
self.start_pos.clone(),
|
||||||
self.end_pos.clone(),
|
self.end_pos.clone(),
|
||||||
),
|
),
|
||||||
@@ -190,11 +190,11 @@ impl Lexer {
|
|||||||
(' ', _) | ('\r', _) | ('\t', _) => Ok(None),
|
(' ', _) | ('\r', _) | ('\t', _) => Ok(None),
|
||||||
('\n', _) => Ok(None),
|
('\n', _) => Ok(None),
|
||||||
('"', _) => self.string(),
|
('"', _) => self.string(),
|
||||||
(c, _) if c.is_digit(10) => self.number(),
|
(c, _) if c.is_ascii_digit() => self.number(),
|
||||||
(c, _) if c.is_alphanumeric() || c == '_' => self.identifier(),
|
(c, _) if c.is_alphanumeric() || c == '_' => self.identifier(),
|
||||||
_ => Err(LoxError::LexicalError {
|
_ => Err(LoxError::LexicalError {
|
||||||
source_slice: SourceSlice::from_positions(
|
source_slice: SourceSlice::from_positions(
|
||||||
self.source_id.clone(),
|
self.source_id,
|
||||||
self.start_pos.clone(),
|
self.start_pos.clone(),
|
||||||
self.end_pos.clone(),
|
self.end_pos.clone(),
|
||||||
),
|
),
|
||||||
@@ -210,7 +210,7 @@ impl Lexer {
|
|||||||
if self.is_at_end() {
|
if self.is_at_end() {
|
||||||
return Err(LoxError::LexicalError {
|
return Err(LoxError::LexicalError {
|
||||||
source_slice: SourceSlice::from_positions(
|
source_slice: SourceSlice::from_positions(
|
||||||
self.source_id.clone(),
|
self.source_id,
|
||||||
self.start_pos.clone(),
|
self.start_pos.clone(),
|
||||||
self.end_pos.clone(),
|
self.end_pos.clone(),
|
||||||
),
|
),
|
||||||
@@ -226,14 +226,14 @@ impl Lexer {
|
|||||||
|
|
||||||
fn number(&mut self) -> LoxResult<Option<Token>> {
|
fn number(&mut self) -> LoxResult<Option<Token>> {
|
||||||
// Leggi la parte intera
|
// Leggi la parte intera
|
||||||
while self.peek().is_digit(10) {
|
while self.peek().is_ascii_digit() {
|
||||||
self.advance();
|
self.advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Controlla se c'è una parte decimale
|
// Controlla se c'è una parte decimale
|
||||||
let has_decimal = if self.peek() == '.' && self.peek_next().is_digit(10) {
|
let has_decimal = if self.peek() == '.' && self.peek_next().is_ascii_digit() {
|
||||||
self.advance(); // consuma il '.'
|
self.advance(); // consuma il '.'
|
||||||
while self.peek().is_digit(10) {
|
while self.peek().is_ascii_digit() {
|
||||||
self.advance();
|
self.advance();
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
|
|||||||
+35
-22
@@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
common::{
|
common::{
|
||||||
ast::{AstNode, Expr},
|
ast::{AstNode, Expr},
|
||||||
base_value::{BaseValue, LoxFunction},
|
base_value::{BaseValue, LoxFunction, Struct},
|
||||||
lox_result::{parse_error, runtime_error, LoxResult},
|
lox_result::{LoxResult, parse_error, runtime_error},
|
||||||
types::Type,
|
types::Type,
|
||||||
},
|
},
|
||||||
frontend::{
|
frontend::{
|
||||||
@@ -224,10 +224,31 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn struct_declaration(&mut self, start_slice: SourceSlice) -> LoxResult<AstNode> {
|
fn struct_declaration(&mut self, start_slice: SourceSlice) -> LoxResult<AstNode> {
|
||||||
self.consume(TokenType::Struct, "Expect 'struct' after '::'")?;
|
|
||||||
self.consume(TokenType::LeftBrace, "Expect '{' after 'struct'")?;
|
self.consume(TokenType::LeftBrace, "Expect '{' after 'struct'")?;
|
||||||
|
let mut fields: Vec<(String, Type)> = vec![];
|
||||||
todo!()
|
while self.peek().token_type != TokenType::RightBrace {
|
||||||
|
let field_name = self
|
||||||
|
.consume(TokenType::Identifier, "Expect identifier after '{'")?
|
||||||
|
.clone();
|
||||||
|
self.consume(TokenType::Colon, "Expect ':' after field name")?;
|
||||||
|
let field_type = self
|
||||||
|
.consume_type_name("Expect type name after ':'")?
|
||||||
|
.clone();
|
||||||
|
self.consume(TokenType::Comma, "Expect ',' after field type")?;
|
||||||
|
fields.push((field_name.lexeme, Type::Unresolved(field_type)));
|
||||||
|
}
|
||||||
|
let end_slice = self
|
||||||
|
.consume(TokenType::RightBrace, "Expect '}' after struct fields")?
|
||||||
|
.source_slice
|
||||||
|
.clone();
|
||||||
|
let source_slice = SourceSlice::from_source_slices(start_slice, end_slice);
|
||||||
|
Ok(AstNode::new_expression(
|
||||||
|
Expr::Literal {
|
||||||
|
value: Box::new(BaseValue::Struct(Box::new(Struct { fields }))),
|
||||||
|
},
|
||||||
|
source_slice,
|
||||||
|
"Struct".to_string(),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn function_declaration(&mut self, start_slice: SourceSlice) -> LoxResult<AstNode> {
|
fn function_declaration(&mut self, start_slice: SourceSlice) -> LoxResult<AstNode> {
|
||||||
@@ -269,13 +290,13 @@ impl Parser {
|
|||||||
let body = self.statement()?;
|
let body = self.statement()?;
|
||||||
Ok(AstNode::new_expression(
|
Ok(AstNode::new_expression(
|
||||||
Expr::Literal {
|
Expr::Literal {
|
||||||
value: Box::new(BaseValue::Function(LoxFunction {
|
value: Box::new(BaseValue::Function(Box::new(LoxFunction {
|
||||||
parameters,
|
parameters,
|
||||||
return_type: Type::Unresolved(return_type.clone()),
|
return_type: Type::Unresolved(return_type.clone()),
|
||||||
body,
|
body,
|
||||||
closure: None,
|
closure: None,
|
||||||
guard,
|
guard,
|
||||||
})),
|
}))),
|
||||||
},
|
},
|
||||||
combine_position.clone(),
|
combine_position.clone(),
|
||||||
return_type.clone(),
|
return_type.clone(),
|
||||||
@@ -328,11 +349,7 @@ impl Parser {
|
|||||||
start_slice.start_position,
|
start_slice.start_position,
|
||||||
end_slice.end_position,
|
end_slice.end_position,
|
||||||
);
|
);
|
||||||
let label_str = if let Some(label) = label {
|
let label_str = label.unwrap_or_default();
|
||||||
label
|
|
||||||
} else {
|
|
||||||
String::default()
|
|
||||||
};
|
|
||||||
Ok(AstNode::new_statement(
|
Ok(AstNode::new_statement(
|
||||||
Expr::Block {
|
Expr::Block {
|
||||||
statements: Box::new(statements),
|
statements: Box::new(statements),
|
||||||
@@ -351,7 +368,7 @@ impl Parser {
|
|||||||
let combined_slice = SourceSlice::from_source_slices(start_slice, end_slice);
|
let combined_slice = SourceSlice::from_source_slices(start_slice, end_slice);
|
||||||
expr.is_statement = true;
|
expr.is_statement = true;
|
||||||
expr.source_slice = combined_slice;
|
expr.source_slice = combined_slice;
|
||||||
return Ok(expr);
|
Ok(expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn return_statement(&mut self, label: Option<String>) -> LoxResult<AstNode> {
|
fn return_statement(&mut self, label: Option<String>) -> LoxResult<AstNode> {
|
||||||
@@ -374,11 +391,7 @@ impl Parser {
|
|||||||
let semicolon = self.consume(TokenType::Semicolon, "Expect ';' after return value.")?;
|
let semicolon = self.consume(TokenType::Semicolon, "Expect ';' after return value.")?;
|
||||||
let end_slice = semicolon.source_slice.clone();
|
let end_slice = semicolon.source_slice.clone();
|
||||||
let combined_slice = SourceSlice::from_source_slices(start_slice, end_slice);
|
let combined_slice = SourceSlice::from_source_slices(start_slice, end_slice);
|
||||||
let label_str = if let Some(label) = label {
|
let label_str = label.unwrap_or_default();
|
||||||
label
|
|
||||||
} else {
|
|
||||||
String::default()
|
|
||||||
};
|
|
||||||
Ok(AstNode::new_statement(
|
Ok(AstNode::new_statement(
|
||||||
Expr::Return {
|
Expr::Return {
|
||||||
expression: Box::new(expr),
|
expression: Box::new(expr),
|
||||||
@@ -653,7 +666,7 @@ impl Parser {
|
|||||||
// Estendi il source_slice per includere le parentesi di chiusura
|
// Estendi il source_slice per includere le parentesi di chiusura
|
||||||
let end_slice = self.previous().source_slice.end_position.clone();
|
let end_slice = self.previous().source_slice.end_position.clone();
|
||||||
let full_slice = SourceSlice {
|
let full_slice = SourceSlice {
|
||||||
source_id: callee.source_slice.source_id.clone(),
|
source_id: callee.source_slice.source_id,
|
||||||
start_position: start_slice.clone(),
|
start_position: start_slice.clone(),
|
||||||
end_position: end_slice.clone(),
|
end_position: end_slice.clone(),
|
||||||
};
|
};
|
||||||
@@ -779,7 +792,7 @@ impl Parser {
|
|||||||
|
|
||||||
fn peek(&self) -> &Token {
|
fn peek(&self) -> &Token {
|
||||||
if self.is_at_end() {
|
if self.is_at_end() {
|
||||||
&self.tokens.last().unwrap()
|
self.tokens.last().unwrap()
|
||||||
} else {
|
} else {
|
||||||
&self.tokens[self.current]
|
&self.tokens[self.current]
|
||||||
}
|
}
|
||||||
@@ -787,7 +800,7 @@ impl Parser {
|
|||||||
|
|
||||||
fn peek_next(&self) -> &Token {
|
fn peek_next(&self) -> &Token {
|
||||||
if self.is_at_end() {
|
if self.is_at_end() {
|
||||||
&self.peek()
|
self.peek()
|
||||||
} else {
|
} else {
|
||||||
&self.tokens[self.current + 1]
|
&self.tokens[self.current + 1]
|
||||||
}
|
}
|
||||||
@@ -806,7 +819,7 @@ impl Parser {
|
|||||||
self.advance();
|
self.advance();
|
||||||
Ok(self.previous())
|
Ok(self.previous())
|
||||||
} else {
|
} else {
|
||||||
return parse_error(self.peek().source_slice.clone(), message);
|
parse_error(self.peek().source_slice.clone(), message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::{
|
|||||||
io::ErrorKind,
|
io::ErrorKind,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::common::lox_result::{io_error, LoxResult};
|
use crate::common::lox_result::{LoxResult, io_error};
|
||||||
|
|
||||||
pub struct SourceRegistry {
|
pub struct SourceRegistry {
|
||||||
pub sources: Vec<SourceFile>,
|
pub sources: Vec<SourceFile>,
|
||||||
@@ -226,3 +226,9 @@ impl SourceRegistry {
|
|||||||
line_of_code
|
line_of_code
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for SourceRegistry {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ impl PrettyContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn should_truncate(&self) -> bool {
|
fn should_truncate(&self) -> bool {
|
||||||
self.config.max_depth.map_or(false, |max| self.depth >= max)
|
self.config.max_depth.is_some_and(|max| self.depth >= max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,17 +102,17 @@ impl Token {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if config.colored {
|
if config.colored {
|
||||||
format!("{}", self.colored_type())
|
self.colored_type().to_string()
|
||||||
} else {
|
} else {
|
||||||
format!("{}", self.token_type_symbol())
|
self.token_type_symbol().to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if config.colored {
|
if config.colored {
|
||||||
format!("{}", self.colored_type())
|
self.colored_type().to_string()
|
||||||
} else {
|
} else {
|
||||||
format!("{}", self.token_type_symbol())
|
self.token_type_symbol().to_string()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-21
@@ -33,12 +33,10 @@ fn main() -> LoxResult<()> {
|
|||||||
println!("running {file_path:?}");
|
println!("running {file_path:?}");
|
||||||
let mut lox = LoxInterpreter::new(debug);
|
let mut lox = LoxInterpreter::new(debug);
|
||||||
|
|
||||||
let res = match file_path {
|
match file_path {
|
||||||
Some(path) => lox.run_file(&path, stage),
|
Some(path) => lox.run_file(&path, stage),
|
||||||
None => lox.run_prompt(stage),
|
None => lox.run_prompt(stage),
|
||||||
};
|
}
|
||||||
|
|
||||||
res
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_args(args: &[String]) -> (ExecutionStage, Option<String>, bool) {
|
fn parse_args(args: &[String]) -> (ExecutionStage, Option<String>, bool) {
|
||||||
@@ -140,13 +138,12 @@ impl LoxInterpreter {
|
|||||||
|
|
||||||
match self.source_registry.add_source_string(line.to_string()) {
|
match self.source_registry.add_source_string(line.to_string()) {
|
||||||
Ok(source_id) => {
|
Ok(source_id) => {
|
||||||
match self.process_source(source_id, stage, self.debug) {
|
if let Ok(result) = self.process_source(source_id, stage, self.debug) {
|
||||||
Ok(result) => match stage {
|
match stage {
|
||||||
ExecutionStage::Tokens => println!("Tokens: {}", result),
|
ExecutionStage::Tokens => println!("Tokens: {}", result),
|
||||||
ExecutionStage::Ast => println!("AST: {}", result),
|
ExecutionStage::Ast => println!("AST: {}", result),
|
||||||
ExecutionStage::Full => println!("Result: {}", result),
|
ExecutionStage::Full => println!("Result: {}", result),
|
||||||
},
|
}
|
||||||
Err(_) => {} // Errore già stampato in process_source
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => eprintln!("Error: {}", e),
|
Err(e) => eprintln!("Error: {}", e),
|
||||||
@@ -167,9 +164,8 @@ impl LoxInterpreter {
|
|||||||
let source_content = self.source_registry.get_by_id(source_id).content.clone();
|
let source_content = self.source_registry.get_by_id(source_id).content.clone();
|
||||||
let mut lexer = Lexer::new(source_content, source_id);
|
let mut lexer = Lexer::new(source_content, source_id);
|
||||||
|
|
||||||
lexer.scans_tokens().or_else(|err| {
|
lexer.scans_tokens().inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,9 +173,8 @@ impl LoxInterpreter {
|
|||||||
fn parse_to_ast(&self, source_id: SourceId) -> LoxResult<Vec<AstNode>> {
|
fn parse_to_ast(&self, source_id: SourceId) -> LoxResult<Vec<AstNode>> {
|
||||||
let tokens = self.tokenize(source_id)?;
|
let tokens = self.tokenize(source_id)?;
|
||||||
|
|
||||||
Parser::new(tokens).parse().or_else(|err| {
|
Parser::new(tokens).parse().inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,9 +191,8 @@ impl LoxInterpreter {
|
|||||||
if debug {
|
if debug {
|
||||||
println!("Executing statement {}: {:?}", index, stmt);
|
println!("Executing statement {}: {:?}", index, stmt);
|
||||||
}
|
}
|
||||||
result = Some(interpreter.evaluate(stmt.clone()).or_else(|err| {
|
result = Some(interpreter.evaluate(stmt.clone()).inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})?);
|
})?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,9 +225,8 @@ impl LoxInterpreter {
|
|||||||
let mut lexer = Lexer::new(source_content, source_id);
|
let mut lexer = Lexer::new(source_content, source_id);
|
||||||
|
|
||||||
// Stage 1: Tokenization
|
// Stage 1: Tokenization
|
||||||
let tokens = lexer.scans_tokens().or_else(|err| {
|
let tokens = lexer.scans_tokens().inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Se debug è attivo, mostra sempre i tokens
|
// Se debug è attivo, mostra sempre i tokens
|
||||||
@@ -247,9 +240,8 @@ impl LoxInterpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stage 2: Parsing
|
// Stage 2: Parsing
|
||||||
let ast = Parser::new(tokens).parse().or_else(|err| {
|
let ast = Parser::new(tokens).parse().inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Se debug è attivo, mostra sempre l'AST
|
// Se debug è attivo, mostra sempre l'AST
|
||||||
@@ -272,9 +264,8 @@ impl LoxInterpreter {
|
|||||||
if debug {
|
if debug {
|
||||||
println!("Executing statement {}: {:?}", index, stmt);
|
println!("Executing statement {}: {:?}", index, stmt);
|
||||||
}
|
}
|
||||||
result = Some(interpreter.evaluate(stmt.clone()).or_else(|err| {
|
result = Some(interpreter.evaluate(stmt.clone()).inspect_err(|err| {
|
||||||
err.print_with_context(&self.source_registry);
|
err.print_with_context(&self.source_registry);
|
||||||
Err(err)
|
|
||||||
})?);
|
})?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +286,7 @@ fn format_tokens(tokens: &[crate::frontend::tokens::Token]) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn format_ast(ast: &[AstNode]) -> String {
|
fn format_ast(ast: &[AstNode]) -> String {
|
||||||
use crate::logging::display_ast::{pretty_print_with_config, PrettyConfig};
|
use crate::logging::display_ast::{PrettyConfig, pretty_print_with_config};
|
||||||
|
|
||||||
let config = PrettyConfig {
|
let config = PrettyConfig {
|
||||||
indent: " ".to_string(),
|
indent: " ".to_string(),
|
||||||
|
|||||||
@@ -52,12 +52,12 @@ impl<T> ScopeStack<T> {
|
|||||||
|
|
||||||
/// Update an existing binding in the innermost scope (no-op if absent).
|
/// Update an existing binding in the innermost scope (no-op if absent).
|
||||||
pub fn set_local(&mut self, name: &str, state: T) {
|
pub fn set_local(&mut self, name: &str, state: T) {
|
||||||
if let Some(scope) = self.scopes.last_mut() {
|
if let Some(scope) = self.scopes.last_mut()
|
||||||
if let Some(slot) = scope.get_mut(name) {
|
&& let Some(slot) = scope.get_mut(name)
|
||||||
|
{
|
||||||
*slot = state;
|
*slot = state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Look up `name` in the innermost scope only.
|
/// Look up `name` in the innermost scope only.
|
||||||
pub fn get_local(&self, name: &str) -> Option<&T> {
|
pub fn get_local(&self, name: &str) -> Option<&T> {
|
||||||
@@ -68,7 +68,7 @@ impl<T> ScopeStack<T> {
|
|||||||
pub fn declared_in_current(&self, name: &str) -> bool {
|
pub fn declared_in_current(&self, name: &str) -> bool {
|
||||||
self.scopes
|
self.scopes
|
||||||
.last()
|
.last()
|
||||||
.map_or(false, |scope| scope.contains_key(name))
|
.is_some_and(|scope| scope.contains_key(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Distance (in scopes) from the innermost scope to the one declaring
|
/// Distance (in scopes) from the innermost scope to the one declaring
|
||||||
|
|||||||
Reference in New Issue
Block a user