From 2e71d9e99ec9b5b6b139010050331b33bd3e0dd4 Mon Sep 17 00:00:00 2001 From: Dominic Grimm Date: Sun, 11 Sep 2022 19:32:05 +0200 Subject: [PATCH] [WIP] Add conditions --- hence/src/bin/main.rs | 6 +-- hence/src/lib/assembler.rs | 2 +- hence/src/lib/lexer.rs | 2 +- henceforth/examples/test.fth | 8 +--- henceforth/src/bin/main.rs | 6 +-- henceforth/src/lib/compiler.rs | 32 +++++++++++----- henceforth/src/lib/compiler/instruction.rs | 44 ++++++---------------- henceforth/src/lib/compiler/template.asm | 7 ++-- henceforth/src/lib/lexer.rs | 2 +- henceforth/src/lib/parser.rs | 4 +- 10 files changed, 51 insertions(+), 62 deletions(-) diff --git a/hence/src/bin/main.rs b/hence/src/bin/main.rs index 783479a..580cc1c 100644 --- a/hence/src/bin/main.rs +++ b/hence/src/bin/main.rs @@ -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( diff --git a/hence/src/lib/assembler.rs b/hence/src/lib/assembler.rs index 26a522a..9bb71c4 100644 --- a/hence/src/lib/assembler.rs +++ b/hence/src/lib/assembler.rs @@ -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::>()); diff --git a/hence/src/lib/lexer.rs b/hence/src/lib/lexer.rs index 2c4db7a..b15a625 100644 --- a/hence/src/lib/lexer.rs +++ b/hence/src/lib/lexer.rs @@ -89,7 +89,7 @@ impl assembler::ToCode for Token { } } -pub fn lex(source: String) -> Result> { +pub fn lex(source: &str) -> Result> { let mut chars = source.chars().peekable(); let mut tokens: Vec = vec![]; diff --git a/henceforth/examples/test.fth b/henceforth/examples/test.fth index ad73a56..c1e936e 100644 --- a/henceforth/examples/test.fth +++ b/henceforth/examples/test.fth @@ -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 diff --git a/henceforth/src/bin/main.rs b/henceforth/src/bin/main.rs index 6c8b9f1..ebfd413 100644 --- a/henceforth/src/bin/main.rs +++ b/henceforth/src/bin/main.rs @@ -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(); diff --git a/henceforth/src/lib/compiler.rs b/henceforth/src/lib/compiler.rs index a36a31c..a130282 100644 --- a/henceforth/src/lib/compiler.rs +++ b/henceforth/src/lib/compiler.rs @@ -20,17 +20,17 @@ pub struct Word { pub times_used: usize, } -#[derive(Debug)] +#[derive(Debug, PartialEq, Eq, Hash)] pub struct Condition { pub if_instructions: Vec, pub else_instructions: Vec, -} +} #[derive(Debug)] pub struct Data { pub words: HashMap, - // pub word_graph: - pub conditions: IndexSet, + // pub word_graph: + pub conditions: IndexSet, pub strings: IndexSet, } @@ -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 diff --git a/henceforth/src/lib/compiler/instruction.rs b/henceforth/src/lib/compiler/instruction.rs index 937cbf4..0237ac8 100644 --- a/henceforth/src/lib/compiler/instruction.rs +++ b/henceforth/src/lib/compiler/instruction.rs @@ -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, - else_instructions: Vec, - }, + Condition(usize), Multiple { instruction: Box, @@ -1228,15 +1225,10 @@ impl compiler::Compilable 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 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::>>()?; - let else_compiled = else_instructions - .iter() - .map(|ins| ins.compile(data)) - .collect::>>()?; - 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 { diff --git a/henceforth/src/lib/compiler/template.asm b/henceforth/src/lib/compiler/template.asm index 672a8b3..27a230a 100644 --- a/henceforth/src/lib/compiler/template.asm +++ b/henceforth/src/lib/compiler/template.asm @@ -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 diff --git a/henceforth/src/lib/lexer.rs b/henceforth/src/lib/lexer.rs index bb49c8f..fff7038 100644 --- a/henceforth/src/lib/lexer.rs +++ b/henceforth/src/lib/lexer.rs @@ -33,7 +33,7 @@ pub fn is_space(c: char) -> bool { c.is_whitespace() || c == '\n' } -pub fn lex(source: String) -> Result> { +pub fn lex(source: &str) -> Result> { let mut chars = source.chars().peekable(); let mut tokens: Vec = vec![]; diff --git a/henceforth/src/lib/parser.rs b/henceforth/src/lib/parser.rs index e29a9ee..f1d6e35 100644 --- a/henceforth/src/lib/parser.rs +++ b/henceforth/src/lib/parser.rs @@ -14,7 +14,7 @@ pub fn parse_stack_state(s: Option<&str>) -> Vec { } } -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) -> Result { 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)); }