[WIP] Add conditions

This commit is contained in:
Dominic Grimm 2022-09-11 19:32:05 +02:00
parent 0530522847
commit 2e71d9e99e
No known key found for this signature in database
GPG Key ID: A6C051C716D2CE65
10 changed files with 51 additions and 62 deletions

View File

@ -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(

View File

@ -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<_>>());

View File

@ -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![];

View File

@ -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

View File

@ -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();

View File

@ -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<Instruction>,
pub else_instructions: Vec<Instruction>,
}
}
#[derive(Debug)]
pub struct Data {
pub words: HashMap<String, Word>,
// pub word_graph:
pub conditions: IndexSet<Instruction>,
// pub word_graph:
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

View File

@ -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 {

View File

@ -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

View File

@ -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![];

View File

@ -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));
}