[WIP] Add conditions
This commit is contained in:
parent
0530522847
commit
2e71d9e99e
10 changed files with 51 additions and 62 deletions
|
@ -47,14 +47,14 @@ fn main() -> Result<()> {
|
|||
match args.commands {
|
||||
Commands::Lex { src } => {
|
||||
let assembly = fs::read_to_string(src)?;
|
||||
let tokens = lexer::lex(assembly)?;
|
||||
let tokens = lexer::lex(&assembly)?;
|
||||
dbg!(tokens);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Commands::Parse { src } => {
|
||||
let assembly = fs::read_to_string(src)?;
|
||||
let tokens = lexer::lex(assembly)?;
|
||||
let tokens = lexer::lex(&assembly)?;
|
||||
let ast = parser::parse(tokens)?;
|
||||
dbg!(ast);
|
||||
|
||||
|
@ -62,7 +62,7 @@ fn main() -> Result<()> {
|
|||
}
|
||||
Commands::Assemble { src, bin, dump } => {
|
||||
let assembly = fs::read_to_string(&src)?;
|
||||
let tokens = lexer::lex(assembly)?;
|
||||
let tokens = lexer::lex(&assembly)?;
|
||||
let ast = parser::parse(tokens)?;
|
||||
|
||||
let mut data = assembler::Data::new(
|
||||
|
|
|
@ -337,7 +337,7 @@ impl Data {
|
|||
};
|
||||
|
||||
self.includes.insert(arg);
|
||||
let body = parser::parse(lexer::lex(source)?)?.body;
|
||||
let body = parser::parse(lexer::lex(&source)?)?.body;
|
||||
self.body_stack
|
||||
.extend(body.into_iter().rev().collect::<Vec<_>>());
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ impl assembler::ToCode for Token {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lex(source: String) -> Result<Vec<Token>> {
|
||||
pub fn lex(source: &str) -> Result<Vec<Token>> {
|
||||
let mut chars = source.chars().peekable();
|
||||
let mut tokens: Vec<Token> = vec![];
|
||||
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
\ 1 1 = debug
|
||||
\ if 69 else 42 then debug
|
||||
|
||||
: test 42 ;
|
||||
test debug drop
|
||||
test test debug
|
||||
1 1 = debug
|
||||
if 69 else 42 then debug
|
||||
|
||||
|
|
|
@ -42,14 +42,14 @@ fn main() -> Result<()> {
|
|||
match args.commands {
|
||||
Commands::Lex { src } => {
|
||||
let source = fs::read_to_string(src)?;
|
||||
let tokens = lexer::lex(source)?;
|
||||
let tokens = lexer::lex(&source)?;
|
||||
dbg!(tokens);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Commands::Parse { src } => {
|
||||
let source = fs::read_to_string(src)?;
|
||||
let tokens = lexer::lex(source)?;
|
||||
let tokens = lexer::lex(&source)?;
|
||||
let body = parser::parse(tokens)?;
|
||||
dbg!(body);
|
||||
|
||||
|
@ -62,7 +62,7 @@ fn main() -> Result<()> {
|
|||
dump,
|
||||
} => {
|
||||
let source = fs::read_to_string(&src)?;
|
||||
let tokens = lexer::lex(source)?;
|
||||
let tokens = lexer::lex(&source)?;
|
||||
let ast = parser::parse(tokens)?;
|
||||
let ast = compiler::compile(ast, optimize.unwrap_or(true))?;
|
||||
let assembly = ast.to_code();
|
||||
|
|
|
@ -20,7 +20,7 @@ pub struct Word {
|
|||
pub times_used: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||
pub struct Condition {
|
||||
pub if_instructions: Vec<Instruction>,
|
||||
pub else_instructions: Vec<Instruction>,
|
||||
|
@ -30,7 +30,7 @@ pub struct Condition {
|
|||
pub struct Data {
|
||||
pub words: HashMap<String, Word>,
|
||||
// pub word_graph:
|
||||
pub conditions: IndexSet<Instruction>,
|
||||
pub conditions: IndexSet<Condition>,
|
||||
pub strings: IndexSet<String>,
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ 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()
|
||||
hence::lexer::lex(TEMPLATE_ASM).unwrap()
|
||||
)
|
||||
.unwrap()
|
||||
.body;
|
||||
|
@ -116,10 +116,16 @@ 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)?,
|
||||
});
|
||||
let if_instructions = self.generate_instructions(if_body, optimize)?;
|
||||
let else_instructions = self.generate_instructions(else_body, optimize)?;
|
||||
let id = self
|
||||
.conditions
|
||||
.insert_full(Condition {
|
||||
if_instructions,
|
||||
else_instructions,
|
||||
})
|
||||
.0;
|
||||
instructions.push(Instruction::Condition(id));
|
||||
}
|
||||
parser::ast::Node::Word(x) => {
|
||||
if let Some(ins) = Instruction::from_word(&x) {
|
||||
|
@ -152,6 +158,14 @@ impl Data {
|
|||
]);
|
||||
}
|
||||
|
||||
// conditions
|
||||
for (id, c) in self.conditions.iter().enumerate() {
|
||||
x.push(hence::parser::ast::Node::Label(format!("conditions_{}", id)));
|
||||
x.extend(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
// words
|
||||
for (name, word) in &self
|
||||
.words
|
||||
|
|
|
@ -2,7 +2,7 @@ use anyhow::{bail, Result};
|
|||
|
||||
use crate::compiler;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Instruction {
|
||||
Nop,
|
||||
Debug,
|
||||
|
@ -66,10 +66,7 @@ pub enum Instruction {
|
|||
Mod,
|
||||
Call(String),
|
||||
AsmQuote(String),
|
||||
Condition {
|
||||
if_instructions: Vec<Self>,
|
||||
else_instructions: Vec<Self>,
|
||||
},
|
||||
Condition(usize),
|
||||
|
||||
Multiple {
|
||||
instruction: Box<Self>,
|
||||
|
@ -1228,15 +1225,10 @@ impl compiler::Compilable<compiler::Data, hence::parser::ast::Body> for Instruct
|
|||
Instruction::Call(x) => match data.words.get(x) {
|
||||
Some(w) => {
|
||||
if w.times_used > 1 {
|
||||
Ok(vec![
|
||||
hence::parser::ast::Node::MacroCall {
|
||||
name: "call_stack_jump".to_string(),
|
||||
args: vec![
|
||||
hence::arg::Arg::Variable(format!("words_{}", w.id)),
|
||||
hence::arg::Arg::Variable("OFFSET".to_string())
|
||||
],
|
||||
}
|
||||
])
|
||||
Ok(vec![hence::parser::ast::Node::MacroCall {
|
||||
name: "call_stack_jump".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable(format!("words_{}", w.id))],
|
||||
}])
|
||||
} else {
|
||||
Ok(w.instructions
|
||||
.iter()
|
||||
|
@ -1249,25 +1241,11 @@ 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::Condition {
|
||||
if_instructions,
|
||||
else_instructions,
|
||||
} => {
|
||||
let if_compiled = if_instructions
|
||||
.iter()
|
||||
.map(|ins| ins.compile(data))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
let else_compiled = else_instructions
|
||||
.iter()
|
||||
.map(|ins| ins.compile(data))
|
||||
.collect::<Result<Vec<_>>>()?;
|
||||
dbg!(if_compiled, else_compiled);
|
||||
|
||||
Ok(vec![])
|
||||
}
|
||||
Instruction::AsmQuote(x) => Ok(hence::parser::parse(hence::lexer::lex(x)?)?.body),
|
||||
Instruction::Condition(x) => Ok(vec![hence::parser::ast::Node::MacroCall {
|
||||
name: "call_stack_jump".to_string(),
|
||||
args: vec![hence::arg::Arg::Variable(format!("conditions_{}", x))],
|
||||
}]),
|
||||
|
||||
Instruction::Multiple { instruction, count } => {
|
||||
if *count == 0 {
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
tlr CORE_REG_A
|
||||
.endmacro
|
||||
|
||||
.macro call_stack_jump, prep_call_stack_jump_arg_0_label, prep_call_stack_jump_arg_1_offset
|
||||
.std_rset CORE_REG_C, prep_call_stack_jump_arg_0_label
|
||||
.std_rset CORE_REG_D, (prep_call_stack_jump_arg_1_offset + 7)
|
||||
.macro call_stack_jump, call_stack_jump_arg_0_label
|
||||
.define call_stack_jump_local_offset, OFFSET
|
||||
.std_rset CORE_REG_C, call_stack_jump_arg_0_label
|
||||
.std_rset CORE_REG_D, (call_stack_jump_local_offset + 7)
|
||||
ts call_stack_jump
|
||||
tlr CORE_REG_PC
|
||||
.endmacro
|
||||
|
|
|
@ -33,7 +33,7 @@ pub fn is_space(c: char) -> bool {
|
|||
c.is_whitespace() || c == '\n'
|
||||
}
|
||||
|
||||
pub fn lex(source: String) -> Result<Vec<Token>> {
|
||||
pub fn lex(source: &str) -> Result<Vec<Token>> {
|
||||
let mut chars = source.chars().peekable();
|
||||
let mut tokens: Vec<Token> = vec![];
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn parse_stack_state(s: Option<&str>) -> Vec<String> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn parse_stack_result(s: String) -> ast::StackResult {
|
||||
pub fn parse_stack_result(s: &str) -> ast::StackResult {
|
||||
let mut splitter = s.splitn(2, "--");
|
||||
|
||||
ast::StackResult {
|
||||
|
@ -83,7 +83,7 @@ pub fn parse(tokens: Vec<lexer::Token>) -> Result<ast::AST> {
|
|||
lexer::Token::ParenComment(x)
|
||||
| lexer::Token::BackslashComment(x)
|
||||
| lexer::Token::DoubleDashComment(x) => {
|
||||
let y = x.to_string();
|
||||
let y = &x.to_string();
|
||||
content.next();
|
||||
break Some(parse_stack_result(y));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue