wip addin syntax parser

This commit is contained in:
2026-07-13 07:51:24 +02:00
parent 52f0a5b8f1
commit 956446c170
4 changed files with 48 additions and 93 deletions
+9 -1
View File
@@ -2,8 +2,9 @@ use crate::{
backend::environment::EnvironmentStack, backend::environment::EnvironmentStack,
common::{ common::{
ast::{AstNode, Expr, NodeId}, ast::{AstNode, Expr, NodeId},
base_value::{BaseValue, NativeFunction, Number, Truthy}, base_value::{BaseValue, NativeFunction, Number, Struct, Truthy},
lox_result::{LoxError, LoxResult, runtime_error}, lox_result::{LoxError, LoxResult, runtime_error},
types::Type,
}, },
frontend::{source_registry::SourceSlice, tokens::TokenType}, frontend::{source_registry::SourceSlice, tokens::TokenType},
}; };
@@ -145,6 +146,13 @@ impl Interpreter {
} }
Ok(ret) Ok(ret)
} }
Expr::Struct { fields } => {
let fields: Vec<(String, Type)> = fields
.iter()
.map(|(name, ty)| (name.clone(), ty.clone()))
.collect();
Ok(BaseValue::Struct(Box::new(Struct { fields })))
}
}; };
// Give location-less runtime errors this node's span. // Give location-less runtime errors this node's span.
match result { match result {
+16 -92
View File
@@ -2,8 +2,11 @@ use crate::{
common::{base_value::BaseValue, types::Type}, common::{base_value::BaseValue, types::Type},
frontend::{source_registry::SourceSlice, tokens::TokenType}, frontend::{source_registry::SourceSlice, tokens::TokenType},
}; };
use std::fmt::{Debug, Display};
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::{
collections::HashMap,
fmt::{Debug, Display},
};
/// A unique identity for an AST node, assigned once at construction. /// A unique identity for an AST node, assigned once at construction.
/// ///
@@ -23,7 +26,7 @@ impl NodeId {
} }
} }
#[derive(Clone, PartialEq)] #[derive(Clone, PartialEq, Debug)]
pub enum Expr { pub enum Expr {
Literal { Literal {
value: Box<BaseValue>, value: Box<BaseValue>,
@@ -83,6 +86,9 @@ pub enum Expr {
increment: Box<AstNode>, increment: Box<AstNode>,
body: Box<AstNode>, body: Box<AstNode>,
}, },
Struct {
fields: Box<HashMap<String, Type>>,
},
} }
// Implementazione Display per Expr (per debugging) // Implementazione Display per Expr (per debugging)
@@ -164,100 +170,18 @@ impl std::fmt::Display for Expr {
"For({} = {} in {}) {{\n{}\n}}", "For({} = {} in {}) {{\n{}\n}}",
variable.node, condition.node, increment.node, body.node variable.node, condition.node, increment.node, body.node
), ),
Expr::Struct { fields } => {
let field_strs: Vec<String> = fields
.iter()
.map(|(k, v)| format!("{}: {:?}", k, v))
.collect();
write!(f, "Struct {{ {} }}", field_strs.join(", "))
}
} }
} }
} }
impl Debug for Expr { // Debug is derived on Expr via #[derive(Debug)] above.
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Expr::Literal { value } => write!(f, "{:?} ", value,),
Expr::Binary {
left,
operator,
right,
} => write!(f, "({:?} {:?} {:?}) ", operator, left.node, right.node,),
Expr::Unary { operator, operand } => {
write!(f, "(Unary {:?} {:?}) ", operator, operand.node,)
}
Expr::Grouping { expression } => {
write!(f, "(Grouping {:?})", expression.node,)
}
Expr::Identifier { name } => {
write!(f, "(variable {:?})", name,)
}
Expr::Call { callee, arguments } => write!(
f,
"Call ({}({}))",
callee.node,
arguments
.iter()
.map(|arg| arg.node.to_string())
.collect::<Vec<String>>()
.join(", "),
),
Expr::Assign { name, value } => {
write!(f, "(assign {:?} {:?})", name, value.node,)
}
Expr::If {
condition,
then_branch,
elif_branches,
else_branch,
} => {
let mut result =
format!("IF ({:?}) {{\n{:?}\n}}", condition.node, then_branch.node,);
for (condition, branch) in elif_branches {
result.push_str(&format!(
" ELIF ({:?}) {{\n{:?}\n}}",
condition.node, branch.node,
));
}
if let Some(else_branch) = else_branch {
result.push_str(&format!(" ELSE {{\n{:?}\n}}", else_branch.node,));
}
write!(f, "IfStmt {:?}", result)
}
Expr::Print { expression } => {
write!(f, "Print({:?});", expression.node,)
}
Expr::VarDeclaration {
name,
initializer,
var_type,
} => match initializer {
Some(init) => write!(f, "Var({:?}: {:?} = {:?});", name, var_type, init.node,),
None => write!(f, "Var({:?}: {:?});", name, var_type,),
},
Expr::Return { expression, label } => {
write!(f, "Return({:?}, {}) ;", expression.node, label,)
}
Expr::Block { label, statements } => write!(
f,
"Block [{}] ([\n{:?}\n])",
label,
statements
.iter()
.map(|stmt| format!("{:?}", stmt.node))
.collect::<Vec<_>>()
.join("\t\t\n"),
),
Expr::While { condition, body } => {
write!(f, "While({:?}) {{\n{:?}\n}}", condition.node, body.node,)
}
Expr::For {
variable,
condition,
increment,
body,
} => write!(
f,
"For({:?} = {:?} in {:?}) {{\n{:?}\n}} ",
variable.node, condition.node, increment.node, body.node,
),
}
}
}
#[derive(Clone)] #[derive(Clone)]
pub struct AstNode { pub struct AstNode {
+21
View File
@@ -414,6 +414,27 @@ impl PrettyPrint for Expr {
body.pretty_print(&ctx.child_context(true), f)?; body.pretty_print(&ctx.child_context(true), f)?;
writeln!(f, "{}}}", ctx.child_context(true).indent()) writeln!(f, "{}}}", ctx.child_context(true).indent())
} }
Expr::Struct { fields } => {
if ctx.config.compact {
let field_strs: Vec<String> = fields
.iter()
.map(|(k, v)| format!("{}: {:?}", k, v))
.collect();
write!(f, "struct {{ {} }}", field_strs.join(", "))
} else {
writeln!(f, "{}Struct {{", indent)?;
for (name, ty) in fields.iter() {
writeln!(
f,
"{}{}: {:?},",
ctx.child_context(false).indent(),
name,
ty
)?;
}
write!(f, "{}}}", indent)
}
}
} }
} }
} }
+2
View File
@@ -136,6 +136,8 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &AstNode) -> LoxResult<()> {
visitor.visit_expr(increment)?; visitor.visit_expr(increment)?;
visitor.visit_expr(body) visitor.visit_expr(body)
} }
// Struct declarations carry only type information, no child expressions.
Expr::Struct { .. } => Ok(()),
} }
} }