Skip to content

Commit

Permalink
Implement echo control statements
Browse files Browse the repository at this point in the history
Signed-off-by: Miquel Sabaté Solà <[email protected]>
  • Loading branch information
mssola committed Jan 22, 2025
1 parent 4a7e8db commit 5d06ba1
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 2 deletions.
31 changes: 30 additions & 1 deletion lib/xixanta/src/assembler.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::mapping::{get_mapping_configuration, Mapping};
use crate::node::{ControlType, NodeType, OperationType, PNode, PString};
use crate::node::{ControlType, EchoKind, NodeType, OperationType, PNode, PString};
use crate::object::{Bundle, Context, Object, ObjectType};
use crate::opcodes::{AddressingMode, INSTRUCTIONS};
use crate::parser::Parser;
Expand Down Expand Up @@ -569,6 +569,7 @@ impl<'a> Assembler<'a> {
// On control statements which modify the context, there are
// some further evaluating to do.
match control_type {
ControlType::Echo(t) => self.evaluate_echo(node, t)?,
ControlType::StartRepeat => {
self.evaluate_repeat_statement(node)?;
}
Expand Down Expand Up @@ -708,6 +709,33 @@ impl<'a> Assembler<'a> {
}
}

// Consume an .info/.warning/.error call.
fn evaluate_echo(&mut self, node: &PNode, t: &EchoKind) -> Result<(), Vec<Error>> {
let arg = node.args.as_ref().unwrap().first().unwrap();
let val = &arg.value.value[1..arg.value.value.len() - 1];

match t {
EchoKind::Info => println!("info: {}", val),
EchoKind::Warning => self.warnings.push(Error {
global: false,
line: node.value.line,
source: self.source_for(node),
message: val.to_string(),
}),
EchoKind::Error => {
return Err(Error {
global: false,
line: node.value.line,
source: self.source_for(node),
message: val.to_string(),
}
.into());
}
}

Ok(())
}

// Consume a node which contains a macro call by pushing its bundles now.
fn bundle_call(&mut self, node: &PNode) -> Result<(), Vec<Error>> {
// Get the macro we are trying to reproduce.
Expand Down Expand Up @@ -1372,6 +1400,7 @@ impl<'a> Assembler<'a> {
}
NodeType::Control(ControlType::EndIf) => Ok(()),
NodeType::Control(ControlType::IncludeSource) => Ok(()),
NodeType::Control(ControlType::Echo(_)) => Ok(()),
_ => Err(Error {
line: node.value.line,
message: format!(
Expand Down
13 changes: 13 additions & 0 deletions lib/xixanta/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ impl PString {
}
}

#[derive(Debug, Clone, PartialEq)]
pub enum EchoKind {
Info,
Warning,
Error,
}

/// The type of control function being used. Use this enum in order to detect
/// which control function was detected instead of the node value.
#[derive(Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -150,6 +157,7 @@ pub enum ControlType {
Else,
EndIf,
Defined,
Echo(EchoKind),
}

impl fmt::Display for ControlType {
Expand Down Expand Up @@ -180,6 +188,11 @@ impl fmt::Display for ControlType {
ControlType::Else => write!(f, ".else"),
ControlType::EndIf => write!(f, ".endif"),
ControlType::Defined => write!(f, ".defined"),
ControlType::Echo(t) => match t {
EchoKind::Info => write!(f, ".info"),
EchoKind::Warning => write!(f, ".warning"),
EchoKind::Error => write!(f, ".error"),
},
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion lib/xixanta/src/opcodes.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::node::ControlType;
use crate::node::{ControlType, EchoKind};
use std::collections::HashMap;
use std::fmt;

Expand Down Expand Up @@ -765,6 +765,10 @@ lazy_static! {
functions.insert(String::from(".endif"), Control { control_type: ControlType::EndIf, has_identifier: None, required_args: Some((0, 0)), touches_context: false, only_string: false });
functions.insert(String::from(".def"), Control { control_type: ControlType::Defined, has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: false });
functions.insert(String::from(".defined"), Control { control_type: ControlType::Defined, has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: false });
functions.insert(String::from(".info"), Control { control_type: ControlType::Echo(EchoKind::Info), has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: true });
functions.insert(String::from(".out"), Control { control_type: ControlType::Echo(EchoKind::Info), has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: true });
functions.insert(String::from(".warning"), Control { control_type: ControlType::Echo(EchoKind::Warning), has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: true });
functions.insert(String::from(".error"), Control { control_type: ControlType::Echo(EchoKind::Error), has_identifier: None, required_args: Some((1, 1)), touches_context: false, only_string: true });

functions
};
Expand Down

0 comments on commit 5d06ba1

Please sign in to comment.