[WIP] Add conditions

This commit is contained in:
Dominic Grimm 2022-09-11 18:02:56 +02:00
parent 7943b1607b
commit 0530522847
No known key found for this signature in database
GPG key ID: A6C051C716D2CE65
8 changed files with 338 additions and 180 deletions

View file

@ -1,6 +1,7 @@
use anyhow::{bail, Result};
use indexmap::IndexSet;
use itertools::Itertools;
use lazy_static::lazy_static;
use std::collections::HashMap;
use crate::parser;
@ -19,21 +20,45 @@ pub struct Word {
pub times_used: usize,
}
#[derive(Debug)]
pub struct Condition {
pub if_instructions: Vec<Instruction>,
pub else_instructions: Vec<Instruction>,
}
#[derive(Debug)]
pub struct Data {
pub words: HashMap<String, Word>,
// pub word_graph:
pub conditions: IndexSet<Instruction>,
pub strings: IndexSet<String>,
}
pub const TEMPLATE_ASM: &str = include_str!("compiler/template.asm");
lazy_static! {
#[derive(Debug)]
pub static ref TEMPLATE: hence::parser::ast::Body = hence::parser::parse(
hence::lexer::lex(TEMPLATE_ASM.to_string()).unwrap()
)
.unwrap()
.body;
}
impl Data {
pub fn default() -> Self {
Self {
words: HashMap::new(),
conditions: IndexSet::new(),
strings: IndexSet::new(),
}
}
pub fn generate_instructions(&mut self, body: parser::ast::Body, optimize: bool) -> Result<Vec<Instruction>> {
pub fn generate_instructions(
&mut self,
body: parser::ast::Body,
optimize: bool,
) -> Result<Vec<Instruction>> {
let mut instructions: Vec<Instruction> = vec![];
let mut iter = body.into_iter().peekable();
while let Some(node) = iter.next() {
@ -90,6 +115,12 @@ impl Data {
},
);
}
parser::ast::Node::Condition { if_body, else_body } => {
instructions.push(Instruction::Condition {
if_instructions: self.generate_instructions(if_body, optimize)?,
else_instructions: self.generate_instructions(else_body, optimize)?,
});
}
parser::ast::Node::Word(x) => {
if let Some(ins) = Instruction::from_word(&x) {
instructions.push(ins);
@ -106,174 +137,10 @@ impl Data {
Ok(instructions)
}
pub fn embed(&self, body: hence::parser::ast::Body) -> hence::parser::ast::Body {
let mut x = vec![
// includes
hence::parser::ast::Node::MacroCall {
name: "include".to_string(),
args: vec![hence::arg::Arg::String("$lib/core.asm".to_string())],
},
hence::parser::ast::Node::MacroCall {
name: "include".to_string(),
args: vec![hence::arg::Arg::String("$lib/std.asm".to_string())],
},
hence::parser::ast::Node::MacroCall {
name: "include".to_string(),
args: vec![hence::arg::Arg::String("$lib/main.asm".to_string())],
},
// constants
hence::parser::ast::Node::MacroCall {
name: "define".to_string(),
args: vec![
hence::arg::Arg::Variable("MEM_CALL_STACK".to_string()),
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_LOOP_I".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,
},
],
},
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
// stack_transfer_alu
hence::parser::ast::Node::MacroCall {
name: "macro".to_string(),
args: vec![hence::arg::Arg::Variable("stack_transfer_alu".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_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: "endmacro".to_string(),
args: vec![],
},
// call_word
hence::parser::ast::Node::MacroCall {
name: "macro".to_string(),
args: vec![
hence::arg::Arg::Variable("call_word".to_string()),
hence::arg::Arg::Variable("call_word_arg_0_label".to_string()),
],
},
hence::parser::ast::Node::Call {
name: "ts".to_string(),
arg: Some(hence::arg::Arg::BinaryExpression {
left: Box::new(hence::arg::Arg::Variable("OFFSET".to_string())),
right: Box::new(hence::arg::Arg::Number(3 + 3 + 3 + 1 + 3 + 1)),
op: hence::arg::BinaryExpressionOperator::Add,
}),
},
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: "ts".to_string(),
arg: Some(hence::arg::Arg::Variable("MEM_CALL_STACK".to_string())),
},
hence::parser::ast::Node::Call {
name: "set".to_string(),
arg: None,
},
hence::parser::ast::Node::Call {
name: "ts".to_string(),
arg: Some(hence::arg::Arg::Variable(
"call_word_arg_0_label".to_string(),
)),
},
hence::parser::ast::Node::Call {
// tlr CORE_REG_PC -> tlr 0 -> tlr
name: "tlr".to_string(),
arg: Some(hence::arg::Arg::Variable("CORE_REG_PC".to_string())),
},
hence::parser::ast::Node::MacroCall {
name: "endmacro".to_string(),
args: vec![],
},
// return_word
hence::parser::ast::Node::MacroCall {
name: "macro".to_string(),
args: vec![hence::arg::Arg::Variable("return_word".to_string())],
},
hence::parser::ast::Node::MacroCall {
name: "std_get".to_string(),
args: vec![hence::arg::Arg::Variable("MEM_CALL_STACK".to_string())],
},
hence::parser::ast::Node::Call {
name: "tlr".to_string(),
arg: Some(hence::arg::Arg::Variable("CORE_REG_PC".to_string())),
},
hence::parser::ast::Node::MacroCall {
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(),
args: vec![],
},
// data
hence::parser::ast::Node::Label("data".to_string()),
hence::parser::ast::Node::Label("data_strings".to_string()),
];
pub fn embed(&self, body: hence::parser::ast::Body) -> Result<hence::parser::ast::Body> {
let mut x = TEMPLATE.to_vec();
// strings
for (id, s) in self.strings.iter().enumerate() {
x.extend([
hence::parser::ast::Node::Label(format!("data_strings_{}", id)),
@ -286,7 +153,6 @@ impl Data {
}
// words
x.push(hence::parser::ast::Node::Label("words".to_string()));
for (name, word) in &self
.words
.iter()
@ -308,7 +174,7 @@ impl Data {
.flatten(),
);
x.push(hence::parser::ast::Node::MacroCall {
name: "return_word".to_string(),
name: "return_call_stack_jump".to_string(),
args: vec![],
});
}
@ -326,7 +192,7 @@ impl Data {
args: vec![],
});
x
Ok(x)
}
}
@ -344,6 +210,6 @@ pub fn compile(ast: parser::ast::AST, optimize: bool) -> Result<hence::parser::a
.into_iter()
.flatten()
.collect(),
),
)?,
})
}