wip addin syntax parser
This commit is contained in:
@@ -2,8 +2,9 @@ use crate::{
|
||||
backend::environment::EnvironmentStack,
|
||||
common::{
|
||||
ast::{AstNode, Expr, NodeId},
|
||||
base_value::{BaseValue, NativeFunction, Number, Truthy},
|
||||
base_value::{BaseValue, NativeFunction, Number, Struct, Truthy},
|
||||
lox_result::{LoxError, LoxResult, runtime_error},
|
||||
types::Type,
|
||||
},
|
||||
frontend::{source_registry::SourceSlice, tokens::TokenType},
|
||||
};
|
||||
@@ -145,6 +146,13 @@ impl Interpreter {
|
||||
}
|
||||
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.
|
||||
match result {
|
||||
|
||||
+16
-92
@@ -2,8 +2,11 @@ use crate::{
|
||||
common::{base_value::BaseValue, types::Type},
|
||||
frontend::{source_registry::SourceSlice, tokens::TokenType},
|
||||
};
|
||||
use std::fmt::{Debug, Display};
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fmt::{Debug, Display},
|
||||
};
|
||||
|
||||
/// 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 {
|
||||
Literal {
|
||||
value: Box<BaseValue>,
|
||||
@@ -83,6 +86,9 @@ pub enum Expr {
|
||||
increment: Box<AstNode>,
|
||||
body: Box<AstNode>,
|
||||
},
|
||||
Struct {
|
||||
fields: Box<HashMap<String, Type>>,
|
||||
},
|
||||
}
|
||||
|
||||
// Implementazione Display per Expr (per debugging)
|
||||
@@ -164,100 +170,18 @@ impl std::fmt::Display for Expr {
|
||||
"For({} = {} in {}) {{\n{}\n}}",
|
||||
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 {
|
||||
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,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
// Debug is derived on Expr via #[derive(Debug)] above.
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AstNode {
|
||||
|
||||
@@ -414,6 +414,27 @@ impl PrettyPrint for Expr {
|
||||
body.pretty_print(&ctx.child_context(true), f)?;
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,6 +136,8 @@ pub fn walk_expr<V: Visitor>(visitor: &mut V, expr: &AstNode) -> LoxResult<()> {
|
||||
visitor.visit_expr(increment)?;
|
||||
visitor.visit_expr(body)
|
||||
}
|
||||
// Struct declarations carry only type information, no child expressions.
|
||||
Expr::Struct { .. } => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user