Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task/branch monitor #22

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 31 additions & 28 deletions src/behavior/builder_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,18 @@ use crate::behavior::tree::DecoratorType::{HasAltCall, PredIs};
use crate::common::error::ErrorGen;
use crate::parser::types::{Global, ProvidedFunctionality};

pub type SimpleAST = HashMap<String, HashMap<String, HashMap<String, HashMap<String, Vec<Probe>>>>>;
pub struct SimpleAST {
pub global_stmts: Vec<Statement>,
pub probes: HashMap<String, HashMap<String, HashMap<String, HashMap<String, Vec<Probe>>>>>,
}

pub fn build_behavior_tree(ast: &Whamm, err: &mut ErrorGen) -> (BehaviorTree, SimpleAST) {
let mut visitor = BehaviorTreeBuilder {
tree: BehaviorTree::new(),
ast: HashMap::new(),
ast: SimpleAST {
global_stmts: vec![],
probes: HashMap::new()
},
err,
context_name: "".to_string(),
curr_provider_name: "".to_string(),
Expand All @@ -25,7 +31,7 @@ pub fn build_behavior_tree(ast: &Whamm, err: &mut ErrorGen) -> (BehaviorTree, Si
};
visitor.visit_whamm(ast);

debug!("{:#?}", visitor.ast);
debug!("{:#?}", visitor.ast.probes);
(visitor.tree, visitor.ast)
}

Expand All @@ -45,14 +51,14 @@ impl BehaviorTreeBuilder<'_> {
// =======

fn add_provider_to_ast(&mut self, provider_name: String) {
if !self.ast.contains_key(&provider_name) {
self.ast.insert(provider_name.clone(), HashMap::new());
if !self.ast.probes.contains_key(&provider_name) {
self.ast.probes.insert(provider_name.clone(), HashMap::new());
}
self.curr_provider_name = provider_name;
}

fn add_package_to_ast(&mut self, package_name: String) {
if let Some(provider) = self.ast.get_mut(&self.curr_provider_name) {
if let Some(provider) = self.ast.probes.get_mut(&self.curr_provider_name) {
if !provider.contains_key(&package_name) {
provider.insert(package_name.clone(), HashMap::new());
}
Expand All @@ -63,7 +69,7 @@ impl BehaviorTreeBuilder<'_> {
}

fn add_event_to_ast(&mut self, event_name: String) {
if let Some(provider) = self.ast.get_mut(&self.curr_provider_name) {
if let Some(provider) = self.ast.probes.get_mut(&self.curr_provider_name) {
if let Some(package) = provider.get_mut(&self.curr_package_name) {
if !package.contains_key(&event_name) {
package.insert(event_name.clone(), HashMap::new());
Expand All @@ -76,7 +82,7 @@ impl BehaviorTreeBuilder<'_> {
}

fn add_probe_to_ast(&mut self, probe: &Probe) {
if let Some(provider) = self.ast.get_mut(&self.curr_provider_name) {
if let Some(provider) = self.ast.probes.get_mut(&self.curr_provider_name) {
if let Some(package) = provider.get_mut(&self.curr_package_name) {
if let Some(event) = package.get_mut(&self.curr_event_name) {
if let Some(probes) = event.get_mut(&probe.mode) {
Expand All @@ -97,23 +103,6 @@ impl BehaviorTreeBuilder<'_> {
// = BehaviorTree =
// ================

fn visit_globals(&mut self, globals: &HashMap<String, Global>) {
if globals.len() > 0 {
self.tree.sequence(self.err);

// visit globals
for (_name, global) in globals.iter() {
if global.is_comp_provided {
if let Expr::VarId { name, ..} = &global.var_name {
self.tree.define(self.context_name.clone(),
name.clone(), self.err);
}
}
}
self.tree.exit_sequence(self.err);
}
}

fn visit_provided_globals(&mut self, globals: &HashMap<String, (ProvidedFunctionality, Global)>) {
if globals.len() > 0 {
self.tree.sequence(self.err);
Expand Down Expand Up @@ -318,8 +307,12 @@ impl WhammVisitor<()> for BehaviorTreeBuilder<'_> {

self.tree.enter_scope(self.context_name.clone(), script.name.clone(), self.err);

// visit globals
self.visit_globals(&script.globals);
// NOTE: visit_globals() is no longer needed since initializing user-defined globals is done
// in the init_generator (which doesn't traverse the behavior tree)
// RATHER, we process and emit the statements that do anything with the global vars
// (including declarations since that is an initialization action)
self.ast.global_stmts = script.global_stmts.to_owned();
self.tree.emit_global_stmts(self.err);

script.providers.iter().for_each(| (_name, provider) | {
self.visit_provider(provider)
Expand Down Expand Up @@ -356,7 +349,6 @@ impl WhammVisitor<()> for BehaviorTreeBuilder<'_> {
fn visit_package(&mut self, package: &Package) -> () {
trace!("Entering: BehaviorTreeBuilder::visit_package");
self.context_name += &format!(":{}", package.name.clone());
self.add_package_to_ast(package.name.clone());

if self.is_in_context(r"whamm:script([0-9]+):wasm:bytecode") {
self.visit_bytecode_package(package);
Expand All @@ -368,6 +360,17 @@ impl WhammVisitor<()> for BehaviorTreeBuilder<'_> {
}
};

// Handle AST separately since we don't visit every package
self.add_package_to_ast(package.name.clone());
package.events.iter().for_each(| (_name, event) | {
self.add_event_to_ast(event.name.clone());

// Handle AST separately since we don't visit every probe
event.probe_map.iter().for_each(| (_mode, probe_list) | {
probe_list.iter().for_each(|probe| self.add_probe_to_ast(probe));
});
});

trace!("Exiting: BehaviorTreeBuilder::visit_package");
// Remove this package from `context_name`
self.context_name = self.context_name[..self.context_name.rfind(":").unwrap()].to_string();
Expand Down
13 changes: 13 additions & 0 deletions src/behavior/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,16 @@ impl BehaviorTree {
self
}

pub fn emit_global_stmts(&mut self, err: &mut ErrorGen) -> &mut Self {
let id = self.nodes.len();
self.put_child(Node::Action {
id,
parent: self.curr,
ty: ActionType::EmitGlobalStmts
}, err);
self
}

pub fn emit_body(&mut self, err: &mut ErrorGen) -> &mut Self {
let id = self.nodes.len();
self.put_child(Node::Action {
Expand Down Expand Up @@ -461,6 +471,7 @@ pub enum ActionType {
context: String,
var_name: String
},
EmitGlobalStmts,
EmitPred,
Reset,
EmitBody,
Expand Down Expand Up @@ -589,6 +600,7 @@ pub trait BehaviorVisitor<T> {
ActionType::EnterScope {..} => self.visit_enter_scope(node),
ActionType::ExitScope {..} => self.visit_exit_scope(node),
ActionType::Define {..} => self.visit_define(node),
ActionType::EmitGlobalStmts {..} => self.visit_emit_global_stmts(node),
ActionType::EmitPred {..} => self.visit_emit_pred(node),
ActionType::Reset {..} => self.visit_reset(node),
ActionType::EmitBody {..} => self.visit_emit_body(node),
Expand All @@ -604,6 +616,7 @@ pub trait BehaviorVisitor<T> {
fn visit_enter_scope(&mut self, node: &Node) -> T;
fn visit_exit_scope(&mut self, node: &Node) -> T;
fn visit_define(&mut self, node: &Node) -> T;
fn visit_emit_global_stmts(&mut self, node: &Node) -> T;
fn visit_emit_pred(&mut self, node: &Node) -> T;
fn visit_reset(&mut self, node: &Node) -> T;
fn visit_emit_body(&mut self, node: &Node) -> T;
Expand Down
13 changes: 13 additions & 0 deletions src/behavior/visualize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,19 @@ impl BehaviorVisitor<()> for Visualizer<'_> {
}
}

fn visit_emit_global_stmts(&mut self, node: &TreeNode) -> () {
if let TreeNode::Action { id, ty, parent} = node {
if let ActionType::EmitGlobalStmts = ty {
self.emit_special_action_node(id, "EmitGlobalStmts");
self.emit_edge(parent, id);
} else {
unreachable!()
}
} else {
unreachable!()
}
}

fn visit_emit_pred(&mut self, node: &TreeNode) -> () {
if let TreeNode::Action { id, ty, parent} = node {
if let ActionType::EmitPred = ty {
Expand Down
6 changes: 3 additions & 3 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ pub struct WhammCli {
// global_opts: GlobalOpts,

#[command(subcommand)]
pub(crate) command: Cmd
pub command: Cmd
}

#[derive(Debug, Subcommand)]
pub(crate) enum Cmd {
// /// Generate shell completion
pub enum Cmd {
// /// Generate completion for shell
// Completion {
// /// Shell to generate completion for
// #[arg(arg_enum)]
Expand Down
97 changes: 75 additions & 22 deletions src/common/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::common::terminal::{blue, red, white};
use log::error;
use pest::error::{Error, LineColLocation};
use pest::error::ErrorVariant::ParsingError;
use crate::parser::types::Rule;
use crate::parser::types::{Location, Rule};

const ERR_UNDERLINE_CHAR: char = '^';
const INFO_UNDERLINE_CHAR: char = '-';
Expand Down Expand Up @@ -129,45 +129,98 @@ impl ErrorGen {
self.add_error(err);
}

pub fn duplicate_identifier_error(&mut self, fatal: bool, duplicated_id: String, err_line_col: LineColLocation, info_line_col: LineColLocation) {
let err = WhammError {
fatal,
ty: ErrorType::DuplicateIdentifierError {
duplicated_id: duplicated_id.clone()
},
err_loc: Some(CodeLocation {
pub fn get_duplicate_identifier_error(fatal: bool, duplicated_id: String, err_line_col: Option<LineColLocation>, info_line_col: Option<LineColLocation>) -> WhammError {
let err_loc = if let Some(err_line_col) = err_line_col {
Some(CodeLocation {
is_err: true,
message: Some(format!("duplicate definitions for `{}`", duplicated_id)),
line_col: err_line_col,
line_str: None,
line2_str: None
}),
info_loc: Some(CodeLocation {
is_err: true,
})
} else {
None
};
let info_loc = if let Some(info_line_col) = info_line_col {
Some(CodeLocation {
is_err: false,
message: Some(format!("other definition for `{}`", duplicated_id)),
line_col: info_line_col,
line_str: None,
line2_str: None
}),
})
} else {
None
};

WhammError {
fatal,
ty: ErrorType::DuplicateIdentifierError {
duplicated_id: duplicated_id.clone()
},
err_loc,
info_loc,
}
}

pub fn get_duplicate_identifier_error_from_loc(fatal: bool, duplicated_id: String, err_loc: &Option<Location>, info_loc: &Option<Location>) -> WhammError {
let err_loc = if let Some(err_loc) = err_loc {
Some(err_loc.line_col.clone())
} else {
None
};
let info_loc = if let Some(info_loc) = info_loc {
Some(info_loc.line_col.clone())
} else {
None
};
Self::get_duplicate_identifier_error(fatal, duplicated_id, err_loc, info_loc)
}

pub fn duplicate_identifier_error(&mut self, fatal: bool, duplicated_id: String, err_line_col: Option<LineColLocation>, info_line_col: Option<LineColLocation>) {
let err = Self::get_duplicate_identifier_error(fatal, duplicated_id, err_line_col, info_line_col);
self.add_error(err);
}

pub fn type_check_error(&mut self, fatal: bool, message: String, line_col: LineColLocation) {
let err = WhammError {
pub fn get_type_check_error(fatal: bool, message: String, loc: &Option<LineColLocation>) -> WhammError {
let loc = if let Some(loc) = loc {
Some(CodeLocation {
is_err: false,
message: Some(message.clone()),
line_col: loc.clone(),
line_str: None,
line2_str: None
})
} else {
None
};

WhammError {
fatal,
ty: ErrorType::TypeCheckError {
message: message.clone()
},
err_loc: Some(CodeLocation {
is_err: true,
message: Some(message),
line_col,
line_str: None,
line2_str: None
}),
err_loc: loc,
info_loc: None
}
}

pub fn get_type_check_error_from_loc(fatal: bool, message: String, line_col: &Option<Location>) -> WhammError {
let loc = if let Some(loc) = line_col {
Some(loc.line_col.clone())
} else {
None
};
Self::get_type_check_error(fatal, message, &loc)
}

pub fn type_check_error(&mut self, fatal: bool, message: String, line_col: &Option<LineColLocation>) {
let err = Self::get_type_check_error(fatal, message, line_col);
self.add_error(err);
}

pub fn type_check_error_from_loc(&mut self, fatal: bool, message: String, loc: &Option<Location>) {
let err = Self::get_type_check_error_from_loc(fatal, message, loc);
self.add_error(err);
}

Expand Down Expand Up @@ -498,7 +551,7 @@ impl WhammError {
print_empty(&spacing, &mut buffer);
} else {
// This error isn't tied to a specific code location
blue(false, format!(" --> "), &mut buffer);
blue(false, " --> ".to_string(), &mut buffer);
blue(false, format!("{script_path}\n\n"), &mut buffer);
}
writer.print(&buffer).expect("Uh oh, something went wrong while printing to terminal");
Expand Down
5 changes: 4 additions & 1 deletion src/common/terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ pub fn red(bold: bool, s: String, buffer: &mut Buffer) {
pub fn white(bold: bool, s: String, buffer: &mut Buffer) {
color(s, buffer, bold, false, Color::Rgb(193,193,193))
}
pub fn white_italics(bold: bool, s: String, buffer: &mut Buffer) {
pub fn grey(bold: bool, s: String, buffer: &mut Buffer) {
color(s, buffer, bold, false, Color::White)
}
pub fn grey_italics(bold: bool, s: String, buffer: &mut Buffer) {
color(s, buffer, bold, true, Color::White)
}
pub fn yellow(bold: bool, s: String, buffer: &mut Buffer) {
Expand Down
Loading
Loading