From fe84a38ddc18c0151f1a9c75aabbf5d43d6495df Mon Sep 17 00:00:00 2001 From: Max Oberaigner Date: Tue, 28 May 2024 15:06:41 +0200 Subject: [PATCH] intermediate commit --- rust/godot-plugin/src/conversion.rs | 111 +++++++++++++++++++++++----- rust/godot-plugin/src/lib.rs | 28 +------ 2 files changed, 96 insertions(+), 43 deletions(-) diff --git a/rust/godot-plugin/src/conversion.rs b/rust/godot-plugin/src/conversion.rs index 1fa6249..3732590 100644 --- a/rust/godot-plugin/src/conversion.rs +++ b/rust/godot-plugin/src/conversion.rs @@ -1,67 +1,144 @@ use godot::prelude::*; -use crate::GodotASTNode; +use compiler::Ast; -pub fn to_godot_ast(a: &compiler::ast::Statement) -> Gd { +#[allow(dead_code)] +#[derive(GodotClass)] +#[class(init, base=Node)] +pub struct GodotASTNode { + node_type: i64, + path: Array, + member_data: VariantArray, +} + +pub type ASTArray = Array>; +pub type PathArray = Array; + +trait PathNavigatable { + fn top() -> Self; + fn enter(&self) -> Self; + fn exit(&self) -> Self; + fn next(&self) -> Self; +} + +impl PathNavigatable for PathArray { + fn top() -> Self { + array![0] + } + + fn enter(&self) -> Self { + let mut new = self.clone(); + new.push(0); + new + } + + fn exit(&self) -> Self { + assert!(self.len() > 0); + let mut new = self.clone(); + new.pop(); + new + } + + fn next(&self) -> Self { + assert!(self.len() > 0); + let mut new = self.clone(); + new.set(self.len() - 1, self.get(self.len() - 1).unwrap() + 1); + new + } +} + +pub fn ast_to_godot_ast(ast: &Ast) -> ASTArray { + let mut collect = ASTArray::new(); + let mut current_path = PathArray::top(); + + for statement in ast.statements() { + current_path = current_path.next(); + let ast_node = statement_to_godot_ast(statement, ¤t_path); + collect.push(ast_node); + } + + collect +} + +pub fn statement_to_godot_ast( + a: &compiler::ast::Statement, + current_path: &PathArray, +) -> Gd { use compiler::ast::Statement; let node = match a { Statement::MoveRandomly() => GodotASTNode { node_type: 1, - identifier: -1, // TODO + path: current_path.clone(), member_data: array![], }, Statement::MoveRelative(x, y) => GodotASTNode { node_type: 2, - identifier: -1, // TODO + path: current_path.clone(), member_data: varray![x, y], }, Statement::MoveTo(x, y) => GodotASTNode { node_type: 2, - identifier: -1, // TODO + path: current_path.clone(), member_data: varray![x, y], }, Statement::Calc(x) => GodotASTNode { node_type: 3, - identifier: -1, - member_data: varray![expression_to_godot_ast(x)], + path: current_path.clone(), + member_data: varray![expression_to_godot_ast(x, current_path)], // TODO: Add path to subexpr }, }; Gd::from_object(node) } -pub fn expression_to_godot_ast(expr: &compiler::ast::Expression) -> Gd { +pub fn expression_to_godot_ast( + expr: &compiler::ast::Expression, + parent_path: &PathArray, +) -> Gd { use compiler::ast::Expression; + let current_path = parent_path.enter(); let node = match expr { Expression::IntLiteral(a) => GodotASTNode { node_type: 1000, - identifier: -1, + path: current_path.clone(), member_data: varray![a], // Literal Int }, Expression::Addition(a, b) => GodotASTNode { node_type: 2000, - identifier: -1, - member_data: varray![expression_to_godot_ast(a), expression_to_godot_ast(b)], + path: current_path.clone(), + member_data: varray![ + expression_to_godot_ast(a, ¤t_path), + expression_to_godot_ast(b, ¤t_path.next()), + ], }, Expression::Subtraction(a, b) => GodotASTNode { node_type: 2001, - identifier: -1, - member_data: varray![expression_to_godot_ast(a), expression_to_godot_ast(b)], + path: current_path.clone(), + member_data: varray![ + expression_to_godot_ast(a, ¤t_path), + expression_to_godot_ast(b, ¤t_path.next()) + ], }, Expression::Multiplication(a, b) => GodotASTNode { node_type: 2002, - identifier: -1, - member_data: varray![expression_to_godot_ast(a), expression_to_godot_ast(b)], + path: current_path.clone(), + member_data: varray![ + expression_to_godot_ast(a, ¤t_path), + expression_to_godot_ast(b, ¤t_path.next()) + ], }, Expression::Division(a, b) => GodotASTNode { node_type: 2003, - identifier: -1, - member_data: varray![expression_to_godot_ast(a), expression_to_godot_ast(b)], + path: current_path.clone(), + member_data: varray![ + expression_to_godot_ast(a, ¤t_path), + expression_to_godot_ast(b, ¤t_path.next()) + ], }, }; diff --git a/rust/godot-plugin/src/lib.rs b/rust/godot-plugin/src/lib.rs index 1f8d3da..4431430 100644 --- a/rust/godot-plugin/src/lib.rs +++ b/rust/godot-plugin/src/lib.rs @@ -10,10 +10,10 @@ mod state; use godot::builtin::Array; use godot::prelude::*; -use compiler::Ast; use compiler::Compilable; use godot::engine::Engine; +use crate::conversion::ASTArray; use crate::signals::*; use crate::state::*; @@ -61,7 +61,7 @@ impl Api { #[func] fn get_ast() -> ASTArray { let ast = ast().lock().unwrap(); - ast.to_godot_ast() + conversion::ast_to_godot_ast(&ast) } #[func] @@ -81,27 +81,3 @@ impl Api { ast.compile().into() } } - -type ASTArray = Array>; - -trait ToGodotAst { - fn to_godot_ast(&self) -> ASTArray; -} - -impl ToGodotAst for Ast { - fn to_godot_ast(&self) -> ASTArray { - self.statements() - .iter() - .map(conversion::to_godot_ast) - .collect::() - } -} - -#[allow(dead_code)] -#[derive(GodotClass)] -#[class(init, base=Node)] -struct GodotASTNode { - node_type: i64, - identifier: i64, - member_data: VariantArray, -}