Add new words and assembly emedding
This commit is contained in:
parent
053f3c09a2
commit
30b608e5aa
4 changed files with 504 additions and 19 deletions
|
@ -1,2 +1,13 @@
|
|||
1 2 debug
|
||||
1 pick debug
|
||||
asm"
|
||||
.std_get MEM_ALLOC_PTR
|
||||
tls
|
||||
dbg
|
||||
pop
|
||||
"
|
||||
3 cells allot
|
||||
asm"
|
||||
.std_get MEM_ALLOC_PTR
|
||||
tls
|
||||
dbg
|
||||
pop
|
||||
"
|
||||
|
|
|
@ -26,7 +26,7 @@ pub struct Data {
|
|||
}
|
||||
|
||||
impl Data {
|
||||
pub fn new() -> Self {
|
||||
pub fn default() -> Self {
|
||||
Self {
|
||||
words: HashMap::new(),
|
||||
strings: IndexSet::new(),
|
||||
|
@ -35,13 +35,29 @@ impl Data {
|
|||
|
||||
pub fn generate_instructions(&mut self, body: parser::ast::Body) -> Result<Vec<Instruction>> {
|
||||
let mut instructions: Vec<Instruction> = vec![];
|
||||
for node in body {
|
||||
let mut iter = body.into_iter().peekable();
|
||||
while let Some(node) = iter.next() {
|
||||
match node {
|
||||
_ if iter.next_if_eq(&node).is_some() => {
|
||||
let count = iter.by_ref().peeking_take_while(|n| *n == node).count() + 2;
|
||||
instructions.push(Instruction::Multiple {
|
||||
instruction: Box::new(
|
||||
self.generate_instructions(vec![node])?
|
||||
.into_iter()
|
||||
.next()
|
||||
.unwrap(),
|
||||
),
|
||||
count,
|
||||
});
|
||||
}
|
||||
parser::ast::Node::Comment(_) => {}
|
||||
parser::ast::Node::String { mode, string } => {
|
||||
let id = self.strings.insert_full(string).0;
|
||||
instructions.push(match mode.as_str() {
|
||||
"." => Instruction::DotQuote(id),
|
||||
"." => {
|
||||
let id = self.strings.insert_full(string).0;
|
||||
Instruction::DotQuote(id)
|
||||
}
|
||||
"asm" => Instruction::AsmQuote(string),
|
||||
_ => bail!("Unknown string mode: {}", mode),
|
||||
});
|
||||
}
|
||||
|
@ -109,6 +125,17 @@ impl Data {
|
|||
hence::arg::Arg::Variable("CORE_MEM_MEM".to_string()),
|
||||
],
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "define".to_string(),
|
||||
args: vec![
|
||||
hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string()),
|
||||
hence::arg::Arg::BinaryExpression {
|
||||
left: Box::new(hence::arg::Arg::Variable("CORE_MEM_MEM".to_string())),
|
||||
right: Box::new(hence::arg::Arg::Number(16)),
|
||||
op: hence::arg::BinaryExpressionOperator::Add,
|
||||
},
|
||||
],
|
||||
},
|
||||
// macros
|
||||
// stack_transfer_alu
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
|
@ -195,6 +222,22 @@ impl Data {
|
|||
name: "endmacro".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
// setup
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_rset".to_string(),
|
||||
args: vec![
|
||||
hence::arg::Arg::Variable("CORE_REG_A".to_string()),
|
||||
hence::arg::Arg::BinaryExpression {
|
||||
left: Box::new(hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())),
|
||||
right: Box::new(hence::arg::Arg::Number(1)),
|
||||
op: hence::arg::BinaryExpressionOperator::Add,
|
||||
},
|
||||
],
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_set".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())],
|
||||
},
|
||||
// jump_main
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "jump_main".to_string(),
|
||||
|
@ -262,7 +305,7 @@ impl Data {
|
|||
}
|
||||
|
||||
pub fn compile(ast: parser::ast::AST) -> Result<hence::parser::ast::AST> {
|
||||
let mut data = Data::new();
|
||||
let mut data = Data::default();
|
||||
let instructions = data.generate_instructions(ast.body)?;
|
||||
|
||||
Ok(hence::parser::ast::AST {
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{bail, Result};
|
|||
|
||||
use crate::compiler;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Instruction {
|
||||
Nop,
|
||||
Debug,
|
||||
|
@ -63,6 +63,12 @@ pub enum Instruction {
|
|||
Divide,
|
||||
Mod,
|
||||
Call(String),
|
||||
AsmQuote(String),
|
||||
|
||||
Multiple {
|
||||
instruction: Box<Self>,
|
||||
count: usize,
|
||||
},
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
|
@ -291,11 +297,114 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
|
|||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::Rot => Ok(vec![]),
|
||||
Instruction::Nip => Ok(vec![]),
|
||||
Instruction::Rot => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::Nip => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "pop".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::I => Ok(vec![]),
|
||||
Instruction::J => Ok(vec![]),
|
||||
Instruction::Tuck => Ok(vec![]),
|
||||
Instruction::Tuck => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::Fetch => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
|
@ -310,12 +419,165 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
|
|||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::FetchPrint => Ok(vec![]),
|
||||
Instruction::Store => Ok(vec![]),
|
||||
Instruction::PlusStore => Ok(vec![]),
|
||||
Instruction::MinusStore => Ok(vec![]),
|
||||
Instruction::FetchPrint => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "get".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_set".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("CORE_MEM_OUT".to_string())],
|
||||
},
|
||||
]),
|
||||
Instruction::Store => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "set".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::PlusStore => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "get".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_alu".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "set".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::MinusStore => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "get".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_alu".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("CORE_ALU_SUB".to_string())],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "set".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
Instruction::Cells => Ok(vec![]),
|
||||
Instruction::Allot => Ok(vec![]),
|
||||
Instruction::Allot => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_get".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_alu".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("CORE_ALU_ADD".to_string())],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_set".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string())],
|
||||
},
|
||||
]),
|
||||
Instruction::Dot => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
|
@ -344,7 +606,19 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
|
|||
args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())],
|
||||
},
|
||||
]),
|
||||
Instruction::Space => Ok(vec![]),
|
||||
Instruction::Space => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_rset".to_string(),
|
||||
args: vec![
|
||||
hence::arg::Arg::Variable("CORE_REG_A".to_string()),
|
||||
hence::arg::Arg::Char('\n'),
|
||||
],
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_set".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable("CORE_MEM_CHR".to_string())],
|
||||
},
|
||||
]),
|
||||
Instruction::Spaces => Ok(vec![]),
|
||||
Instruction::Cr => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
|
@ -622,6 +896,163 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
|
|||
}
|
||||
None => bail!("Unknown word: {}", x),
|
||||
},
|
||||
Instruction::AsmQuote(x) => {
|
||||
Ok(hence::parser::parse(hence::lexer::lex(x.to_string())?)?.body)
|
||||
}
|
||||
Instruction::Multiple { instruction, count } => {
|
||||
if *count == 0 {
|
||||
Ok(vec![])
|
||||
} else if *count == 1 {
|
||||
Ok(instruction.compile(data)?)
|
||||
} else {
|
||||
match **instruction {
|
||||
Instruction::Nop => Ok(Instruction::Nop.compile(data)?),
|
||||
Instruction::Quit => Ok(Instruction::Quit.compile(data)?),
|
||||
Instruction::Depth => Ok([
|
||||
Instruction::Depth.compile(data)?,
|
||||
Instruction::Multiple {
|
||||
instruction: Box::new(Instruction::Dup),
|
||||
count: count - 1,
|
||||
}
|
||||
.compile(data)?,
|
||||
]
|
||||
.concat()),
|
||||
Instruction::Dup => Ok([
|
||||
Instruction::Dup.compile(data)?,
|
||||
[hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
}]
|
||||
.into_iter()
|
||||
.cycle()
|
||||
.take(count - 1)
|
||||
.collect(),
|
||||
]
|
||||
.concat()),
|
||||
Instruction::Swap => {
|
||||
if count % 2 == 0 {
|
||||
Ok(vec![])
|
||||
} else {
|
||||
Ok(Instruction::Swap.compile(data)?)
|
||||
}
|
||||
}
|
||||
Instruction::Over => Ok([
|
||||
Instruction::Over.compile(data)?,
|
||||
(0..count - 1)
|
||||
.flat_map(|n| {
|
||||
if n % 2 == 0 {
|
||||
vec![
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable(
|
||||
"CORE_REG_A".to_string(),
|
||||
)),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]
|
||||
} else {
|
||||
vec![
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable(
|
||||
"CORE_REG_B".to_string(),
|
||||
)),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
})
|
||||
.collect(),
|
||||
]
|
||||
.concat()),
|
||||
Instruction::Rot => match count % 3 {
|
||||
0 => Ok(vec![]),
|
||||
1 => Ok(Instruction::Rot.compile(data)?),
|
||||
2 => Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tlr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_B".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tsr".to_string(),
|
||||
arg: Some(hence::arg::Arg::Variable("CORE_REG_C".to_string())),
|
||||
},
|
||||
hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
},
|
||||
]),
|
||||
_ => bail!("Remainder of count % 3 cannot be higher than 3"),
|
||||
},
|
||||
Instruction::Nip => Ok([
|
||||
vec![hence::parser::ast::Node::MacroCall {
|
||||
name: "std_ld".to_string(),
|
||||
args: vec![],
|
||||
}],
|
||||
[hence::parser::ast::Node::Call {
|
||||
name: "pop".to_string(),
|
||||
arg: None,
|
||||
}]
|
||||
.into_iter()
|
||||
.cycle()
|
||||
.take(*count)
|
||||
.collect(),
|
||||
vec![hence::parser::ast::Node::Call {
|
||||
name: "tls".to_string(),
|
||||
arg: None,
|
||||
}],
|
||||
]
|
||||
.concat()),
|
||||
_ => {
|
||||
let compiled = instruction.compile(data)?;
|
||||
let len = compiled.len() * count;
|
||||
Ok(compiled.into_iter().cycle().take(len).collect())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use hence::assembler::ToCode;
|
||||
use itertools::Itertools;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub struct StackResult {
|
||||
pub before: Vec<String>,
|
||||
pub after: Vec<String>,
|
||||
|
@ -25,7 +25,7 @@ impl ToCode for StackResult {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Node {
|
||||
Comment(String),
|
||||
String {
|
||||
|
|
Loading…
Reference in a new issue