2022-03-14 01:04:08 -05:00
|
|
|
use vcore::opcodes::Opcode;
|
|
|
|
|
|
2022-04-05 18:05:24 -05:00
|
|
|
use std::collections::BTreeMap;
|
2022-03-16 23:13:02 -05:00
|
|
|
use std::fmt::{Display, Formatter};
|
2022-03-14 01:04:08 -05:00
|
|
|
|
|
|
|
|
/// One of the five arithmetical operators
|
|
|
|
|
#[derive(Debug, PartialEq, Copy, Clone)]
|
2022-03-14 19:13:14 -05:00
|
|
|
pub enum Operator {
|
|
|
|
|
Add,
|
|
|
|
|
Sub,
|
|
|
|
|
Mul,
|
|
|
|
|
Div,
|
|
|
|
|
Mod,
|
|
|
|
|
}
|
2022-03-14 01:04:08 -05:00
|
|
|
|
|
|
|
|
/// An AST node for an instruction argument. This can be a string, number, label reference,
|
|
|
|
|
/// line offset, or an expr containing a sequence of other Nodes joined by same-precedence
|
|
|
|
|
/// `Operator`s.
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2022-04-05 18:05:24 -05:00
|
|
|
pub enum Node {
|
2022-03-14 01:04:08 -05:00
|
|
|
Number(i32),
|
2022-04-05 18:05:24 -05:00
|
|
|
Label(String),
|
|
|
|
|
RelativeLabel(String),
|
2022-03-14 01:04:08 -05:00
|
|
|
AbsoluteOffset(i32),
|
|
|
|
|
RelativeOffset(i32),
|
2022-04-05 18:05:24 -05:00
|
|
|
Expr(Box<Node>, Vec<(Operator, Node)>),
|
2022-03-14 01:04:08 -05:00
|
|
|
}
|
|
|
|
|
|
2022-04-05 18:05:24 -05:00
|
|
|
impl Node {
|
|
|
|
|
pub fn label(lbl: &str) -> Self {
|
|
|
|
|
Self::Label(lbl.to_string())
|
|
|
|
|
}
|
|
|
|
|
pub fn relative_label(lbl: &str) -> Self {
|
|
|
|
|
Self::RelativeLabel(lbl.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-14 01:04:08 -05:00
|
|
|
|
2022-04-05 18:05:24 -05:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub struct Label(pub String);
|
|
|
|
|
|
|
|
|
|
impl Display for Label {
|
2022-03-16 23:13:02 -05:00
|
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
write!(f, "{}", self.0)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-05 18:05:24 -05:00
|
|
|
impl From<&str> for Label {
|
|
|
|
|
fn from(s: &str) -> Self {
|
|
|
|
|
Self(s.to_string())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub type Scope = BTreeMap<String, i32>;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
|
|
|
|
pub enum Macro {
|
|
|
|
|
Include(String),
|
|
|
|
|
If,
|
|
|
|
|
Unless,
|
|
|
|
|
Else,
|
|
|
|
|
While,
|
|
|
|
|
Until,
|
|
|
|
|
Do,
|
|
|
|
|
End,
|
|
|
|
|
}
|
|
|
|
|
|
2022-03-15 22:50:19 -05:00
|
|
|
#[derive(Debug, PartialEq, Clone)]
|
2022-04-05 18:05:24 -05:00
|
|
|
pub enum VASMLine {
|
|
|
|
|
Instruction(Option<Label>, Opcode, Option<Node>),
|
|
|
|
|
Db(Option<Label>, Node),
|
|
|
|
|
StringDb(Option<Label>, String),
|
|
|
|
|
Org(Option<Label>, Node),
|
|
|
|
|
Equ(Label, Node),
|
|
|
|
|
LabelDef(Label),
|
|
|
|
|
Macro(Macro),
|
2022-03-14 01:04:08 -05:00
|
|
|
}
|
2022-03-27 23:10:08 -05:00
|
|
|
|
2022-04-05 18:05:24 -05:00
|
|
|
impl VASMLine {
|
|
|
|
|
pub fn label(&self) -> Option<&Label> {
|
2022-03-27 23:10:08 -05:00
|
|
|
match self {
|
|
|
|
|
VASMLine::Instruction(Some(lbl), _, _)
|
|
|
|
|
| VASMLine::Db(Some(lbl), _)
|
|
|
|
|
| VASMLine::StringDb(Some(lbl), _)
|
|
|
|
|
| VASMLine::Org(Some(lbl), _)
|
|
|
|
|
| VASMLine::Equ(lbl, _)
|
2022-04-05 18:05:24 -05:00
|
|
|
| VASMLine::LabelDef(lbl) => Some(lbl),
|
2022-03-27 23:10:08 -05:00
|
|
|
_ => None,
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-04-01 22:00:18 -05:00
|
|
|
pub fn zero_length(&self) -> bool {
|
|
|
|
|
matches!(
|
|
|
|
|
self,
|
2022-04-05 18:05:24 -05:00
|
|
|
VASMLine::Org(_, _) | VASMLine::Equ(_, _) | VASMLine::LabelDef(_) | VASMLine::Macro(_)
|
2022-04-01 22:00:18 -05:00
|
|
|
)
|
|
|
|
|
}
|
2022-03-27 23:10:08 -05:00
|
|
|
}
|