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