aboutsummaryrefslogtreecommitdiff
path: root/lib/xixanta
diff options
context:
space:
mode:
Diffstat (limited to 'lib/xixanta')
-rw-r--r--lib/xixanta/src/assembler.rs31
-rw-r--r--lib/xixanta/src/node.rs13
-rw-r--r--lib/xixanta/src/opcodes.rs6
3 files changed, 48 insertions, 2 deletions
diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs
index 4ee769b..66fe418 100644
--- a/lib/xixanta/src/assembler.rs
+++ b/lib/xixanta/src/assembler.rs
@@ -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;
@@ -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)?;
}
@@ -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.
@@ -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!(
diff --git a/lib/xixanta/src/node.rs b/lib/xixanta/src/node.rs
index 243b478..8273967 100644
--- a/lib/xixanta/src/node.rs
+++ b/lib/xixanta/src/node.rs
@@ -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)]
@@ -150,6 +157,7 @@ pub enum ControlType {
Else,
EndIf,
Defined,
+ Echo(EchoKind),
}
impl fmt::Display for ControlType {
@@ -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"),
+ },
}
}
}
diff --git a/lib/xixanta/src/opcodes.rs b/lib/xixanta/src/opcodes.rs
index 865b5cd..752f8ea 100644
--- a/lib/xixanta/src/opcodes.rs
+++ b/lib/xixanta/src/opcodes.rs
@@ -1,4 +1,4 @@
-use crate::node::ControlType;
+use crate::node::{ControlType, EchoKind};
use std::collections::HashMap;
use std::fmt;
@@ -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
};