Compare commits

..

2 commits

Author SHA1 Message Date
17eaeb1a2f Add ALU words 2022-09-10 10:28:23 +02:00
783ba9fce0 Fix codegen for escaped args 2022-09-10 10:28:15 +02:00
4 changed files with 380 additions and 38 deletions

View file

@ -31,8 +31,8 @@ pub enum Arg {
impl assembler::ToCode for Arg { impl assembler::ToCode for Arg {
fn to_code(&self) -> String { fn to_code(&self) -> String {
match self { match self {
Arg::Char(x) => format!("'{}'", x), Arg::Char(x) => format!("'{}'", x.escape_default()),
Arg::String(x) => format!("\"{}\"", x), Arg::String(x) => format!("\"{}\"", x.escape_default()),
Arg::Number(x) => x.to_string(), Arg::Number(x) => x.to_string(),
Arg::Variable(x) => x.clone(), Arg::Variable(x) => x.clone(),
Arg::BinaryExpression { left, right, op } => { Arg::BinaryExpression { left, right, op } => {

View file

@ -1,13 +1 @@
asm" random . cr
.std_get MEM_ALLOC_PTR
tls
dbg
pop
"
3 cells allot
asm"
.std_get MEM_ALLOC_PTR
tls
dbg
pop
"

View file

@ -128,7 +128,7 @@ impl Data {
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {
name: "define".to_string(), name: "define".to_string(),
args: vec![ args: vec![
hence::arg::Arg::Variable("MEM_ALLOC_PTR".to_string()), hence::arg::Arg::Variable("MEM_LOOP_I".to_string()),
hence::arg::Arg::BinaryExpression { hence::arg::Arg::BinaryExpression {
left: Box::new(hence::arg::Arg::Variable("CORE_MEM_MEM".to_string())), left: Box::new(hence::arg::Arg::Variable("CORE_MEM_MEM".to_string())),
right: Box::new(hence::arg::Arg::Number(16)), right: Box::new(hence::arg::Arg::Number(16)),
@ -136,6 +136,28 @@ impl Data {
}, },
], ],
}, },
hence::parser::ast::Node::MacroCall {
name: "define".to_string(),
args: vec![
hence::arg::Arg::Variable("MEM_LOOP_J".to_string()),
hence::arg::Arg::BinaryExpression {
left: Box::new(hence::arg::Arg::Variable("MEM_LOOP_I".to_string())),
right: Box::new(hence::arg::Arg::Number(1)),
op: hence::arg::BinaryExpressionOperator::Add,
},
],
},
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("MEM_LOOP_J".to_string())),
right: Box::new(hence::arg::Arg::Number(1)),
op: hence::arg::BinaryExpressionOperator::Add,
},
],
},
// macros // macros
// stack_transfer_alu // stack_transfer_alu
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {

View file

@ -53,6 +53,7 @@ pub enum Instruction {
Max, Max,
Boolean, Boolean,
Invert, Invert,
Random,
Plus, Plus,
OnePlus, OnePlus,
TwoPlus, TwoPlus,
@ -121,6 +122,7 @@ impl Instruction {
"max" => Some(Instruction::Max), "max" => Some(Instruction::Max),
"boolean" => Some(Instruction::Boolean), "boolean" => Some(Instruction::Boolean),
"invert" => Some(Instruction::Invert), "invert" => Some(Instruction::Invert),
"random" => Some(Instruction::Random),
"+" => Some(Instruction::Plus), "+" => Some(Instruction::Plus),
"1+" => Some(Instruction::OnePlus), "1+" => Some(Instruction::OnePlus),
"2+" => Some(Instruction::TwoPlus), "2+" => Some(Instruction::TwoPlus),
@ -361,8 +363,26 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
arg: None, arg: None,
}, },
]), ]),
Instruction::I => Ok(vec![]), Instruction::I => Ok(vec![
Instruction::J => Ok(vec![]), hence::parser::ast::Node::MacroCall {
name: "std_get".to_string(),
args: vec![hence::arg::Arg::Variable("MEM_LOOP_I".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::J => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "std_get".to_string(),
args: vec![hence::arg::Arg::Variable("MEM_LOOP_J".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Tuck => Ok(vec![ Instruction::Tuck => Ok(vec![
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {
name: "std_ld".to_string(), name: "std_ld".to_string(),
@ -611,7 +631,7 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
name: "std_rset".to_string(), name: "std_rset".to_string(),
args: vec![ args: vec![
hence::arg::Arg::Variable("CORE_REG_A".to_string()), hence::arg::Arg::Variable("CORE_REG_A".to_string()),
hence::arg::Arg::Char('\n'), hence::arg::Arg::Char(' '),
], ],
}, },
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {
@ -625,7 +645,7 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
name: "std_rset".to_string(), name: "std_rset".to_string(),
args: vec![ args: vec![
hence::arg::Arg::Variable("CORE_REG_A".to_string()), hence::arg::Arg::Variable("CORE_REG_A".to_string()),
hence::arg::Arg::Number(0x0a), hence::arg::Arg::Char('\n'),
], ],
}, },
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {
@ -700,26 +720,314 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
]) ])
} }
Instruction::Count => Ok(vec![]), Instruction::Count => Ok(vec![]),
Instruction::Not => Ok(vec![]), Instruction::Not => Ok(vec![
Instruction::And => Ok(vec![]), hence::parser::ast::Node::MacroCall {
Instruction::Nand => Ok(vec![]), name: "std_ld".to_string(),
Instruction::Or => Ok(vec![]), args: vec![],
Instruction::Nor => Ok(vec![]), },
Instruction::Xor => Ok(vec![]), hence::parser::ast::Node::Call {
Instruction::Xnor => Ok(vec![]), name: "tlr".to_string(),
Instruction::Lsh => Ok(vec![]), arg: Some(hence::arg::Arg::Variable("CORE_REG_A".to_string())),
Instruction::Rsh => Ok(vec![]), },
Instruction::Compare => Ok(vec![]), hence::parser::ast::Node::MacroCall {
Instruction::Eq => Ok(vec![]), name: "std_alu".to_string(),
Instruction::Neq => Ok(vec![]), args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())],
Instruction::Lt => Ok(vec![]), },
Instruction::Leq => Ok(vec![]), hence::parser::ast::Node::Call {
Instruction::Gt => Ok(vec![]), name: "tls".to_string(),
Instruction::Geq => Ok(vec![]), arg: None,
},
]),
Instruction::And => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_AND".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Nand => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_AND".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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Or => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_OR".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Nor => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_OR".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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Xor => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_XOR".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Xnor => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_XOR".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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_NOT".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Lsh => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_LSH".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Rsh => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_RSH".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Compare => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_CMP".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Eq => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_EQ".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Neq => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_EQ".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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_INV".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Lt => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_LT".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Leq => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_LEQ".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Gt => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_GT".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Geq => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(),
args: vec![],
},
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_GEQ".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Min => Ok(vec![]), Instruction::Min => Ok(vec![]),
Instruction::Max => Ok(vec![]), Instruction::Max => Ok(vec![]),
Instruction::Boolean => Ok(vec![]), Instruction::Boolean => Ok(vec![
Instruction::Invert => 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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_BOL".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Invert => 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_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_INV".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Random => Ok(vec![
hence::parser::ast::Node::MacroCall {
name: "std_alu".to_string(),
args: vec![hence::arg::Arg::Variable("CORE_ALU_RND".to_string())],
},
hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
},
]),
Instruction::Plus => Ok(vec![ Instruction::Plus => Ok(vec![
hence::parser::ast::Node::MacroCall { hence::parser::ast::Node::MacroCall {
name: "stack_transfer_alu".to_string(), name: "stack_transfer_alu".to_string(),
@ -1045,6 +1353,30 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
}], }],
] ]
.concat()), .concat()),
Instruction::I | Instruction::J => Ok([
instruction.compile(data)?,
[hence::parser::ast::Node::Call {
name: "tls".to_string(),
arg: None,
}]
.into_iter()
.cycle()
.take(count - 1)
.collect(),
]
.concat()),
Instruction::Space | Instruction::Cr => Ok([
instruction.compile(data)?,
[hence::parser::ast::Node::Call {
name: "set".to_string(),
arg: None,
}]
.into_iter()
.cycle()
.take(count - 1)
.collect(),
]
.concat()),
_ => { _ => {
let compiled = instruction.compile(data)?; let compiled = instruction.compile(data)?;
let len = compiled.len() * count; let len = compiled.len() * count;