[WIP] Fix assembler
This commit is contained in:
parent
040ab13911
commit
2c67dba4d7
5 changed files with 69 additions and 51 deletions
|
@ -2,7 +2,7 @@ use anyhow::{bail, Context, Result};
|
|||
use indexmap::IndexSet;
|
||||
use itertools::Itertools;
|
||||
use lazy_static::lazy_static;
|
||||
use petgraph::Graph;
|
||||
use petgraph::{graph::NodeIndex, Graph};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::parser;
|
||||
|
@ -10,7 +10,7 @@ use crate::parser;
|
|||
mod instruction;
|
||||
pub use crate::compiler::instruction::Instruction;
|
||||
|
||||
pub const TEMPLATE_ASM: &str = include_str!("compiler/template.asm");
|
||||
pub const TEMPLATE_ASM: &str = include_str!("compiler/templates/default.asm");
|
||||
|
||||
lazy_static! {
|
||||
#[derive(Debug)]
|
||||
|
@ -30,14 +30,14 @@ pub struct Word {
|
|||
pub id: usize,
|
||||
pub instructions: Vec<Instruction>,
|
||||
pub times_used: usize,
|
||||
pub callable_graph_node: petgraph::graph::NodeIndex,
|
||||
pub callable_graph_node: NodeIndex,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Condition {
|
||||
pub if_instructions: Vec<Instruction>,
|
||||
pub else_instructions: Vec<Instruction>,
|
||||
pub callable_graph_node: petgraph::graph::NodeIndex,
|
||||
pub callable_graph_node: NodeIndex,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -48,8 +48,6 @@ pub enum CallableId {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct Data {
|
||||
// pub words: HashMap<String, Word>,
|
||||
// pub conditions: IndexSet<Condition>,
|
||||
pub strings: IndexSet<String>,
|
||||
pub callable_graph: Graph<CallableId, ()>,
|
||||
pub words: HashMap<String, Word>,
|
||||
|
@ -68,6 +66,45 @@ impl Data {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn add_graph_edge(&mut self, origin: NodeIndex, instruction: Instruction) -> Result<()> {
|
||||
match instruction {
|
||||
Instruction::Call(x) => {
|
||||
self.callable_graph.add_edge(
|
||||
origin,
|
||||
self.words
|
||||
.get(&x)
|
||||
.context(format!("Could not get referenced word: {}", x))?
|
||||
.callable_graph_node,
|
||||
(),
|
||||
);
|
||||
}
|
||||
Instruction::Condition(x) => {
|
||||
self.callable_graph.add_edge(
|
||||
origin,
|
||||
self.conditions
|
||||
.get(x)
|
||||
.context(format!("Could not get referenced condition: {}", x))?
|
||||
.callable_graph_node,
|
||||
(),
|
||||
);
|
||||
}
|
||||
Instruction::Multiple { instruction, count: _ } => {
|
||||
self.add_graph_edge(origin, *instruction)?;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn add_graph_edges(&mut self, origin: NodeIndex, ins: Vec<Instruction>) -> Result<()> {
|
||||
for instruction in ins {
|
||||
self.add_graph_edge(origin, instruction)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn generate_instructions(
|
||||
&mut self,
|
||||
body: parser::ast::Body,
|
||||
|
@ -135,45 +172,29 @@ impl Data {
|
|||
.get_mut(&name)
|
||||
.context(format!("Could not get word: {}", name))?
|
||||
.instructions = ins.clone();
|
||||
|
||||
for instruction in ins {
|
||||
match instruction {
|
||||
Instruction::Call(x) => {
|
||||
self.callable_graph.add_edge(
|
||||
origin,
|
||||
self.words
|
||||
.get(&x)
|
||||
.context(format!("Could not get referenced word: {}", x))?
|
||||
.callable_graph_node,
|
||||
(),
|
||||
);
|
||||
}
|
||||
Instruction::Condition(x) => {}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
dbg!(&self);
|
||||
self.add_graph_edges(origin, ins)?;
|
||||
}
|
||||
parser::ast::Node::Condition { if_body, else_body } => {
|
||||
let if_instructions = self.generate_instructions(if_body, optimize)?;
|
||||
let else_instructions = self.generate_instructions(else_body, optimize)?;
|
||||
let id = self.conditions.len();
|
||||
let origin = self.callable_graph.add_node(CallableId::Condition(id));
|
||||
self.conditions.push(Condition {
|
||||
if_instructions,
|
||||
else_instructions,
|
||||
callable_graph_node: self
|
||||
.callable_graph
|
||||
.add_node(CallableId::Condition(id)),
|
||||
if_instructions: if_instructions.clone(),
|
||||
else_instructions: else_instructions.clone(),
|
||||
callable_graph_node: origin,
|
||||
});
|
||||
instructions.push(Instruction::Condition(id));
|
||||
self.callable_graph.add_node(CallableId::Condition(id));
|
||||
self.add_graph_edges(origin, if_instructions)?;
|
||||
self.add_graph_edges(origin, else_instructions)?;
|
||||
dbg!(&self);
|
||||
}
|
||||
parser::ast::Node::Word(x) => {
|
||||
if let Some(ins) = Instruction::from_word(&x) {
|
||||
instructions.push(ins);
|
||||
} else if let Some(w) = self.words.get_mut(&x) {
|
||||
instructions.push(Instruction::Call(x));
|
||||
w.times_used += 1;
|
||||
instructions.push(Instruction::Call(x));
|
||||
} else {
|
||||
bail!("Word does not exist: {}", x);
|
||||
}
|
||||
|
@ -229,7 +250,7 @@ impl Data {
|
|||
// .collect::<Result<Vec<hence::parser::ast::Body>>>()
|
||||
// .unwrap()
|
||||
// .into_iter()
|
||||
// .flatten(),
|
||||
// .flatten()
|
||||
// );
|
||||
// x.push(hence::parser::ast::Node::MacroCall {
|
||||
// name: "return_call_stack_jump".to_string(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue