started implementing stdlib

This commit is contained in:
MCorange
2023-03-20 16:13:34 +02:00
parent 2d5e94608c
commit d536bfcf31
11 changed files with 445 additions and 38 deletions

View File

@@ -6,7 +6,7 @@ use crate::compile::commands::linux_x86_64_compile_and_link;
use super::commands::linux_x86_64_run;
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<i32>{
let mut of_c = PathBuf::from(&args.out_file);
let (mut of_o, mut of_a) = if &args.out_file == &crate::DEFAULT_OUT_FILE.to_string() {
let of_o = PathBuf::from("/tmp/mclang_comp.o");
@@ -405,8 +405,9 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writer.flush()?;
linux_x86_64_compile_and_link(&of_a, &of_o, &of_c, args.quiet)?;
if args.run {
linux_x86_64_run(&of_c, vec![], args.quiet)?;
let c = linux_x86_64_run(&of_c, vec![], args.quiet)?;
return Ok(c);
}
Ok(())
Ok(0)
}

View File

@@ -64,7 +64,7 @@ pub struct Operator {
pub text: String, //? only used for OpType::PushStr
pub addr: i64, //? only used for OpType::PushStr
pub jmp: i32,
pub pos: (String, u32, u32)
pub loc: (String, u32, u32)
}
impl Operator {
@@ -75,7 +75,7 @@ impl Operator {
jmp: 0,
addr: -1,
text,
pos: (file, row, col)
loc: (file, row, col)
}
}

View File

@@ -14,7 +14,7 @@ fn stack_pop(stack: &mut Vec<u64>, pos: &(String, u32, u32)) -> Result<u64> {
}
}
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<i32>{
let mut stack: Vec<u64> = Vec::new();
let mut ti = 0;
let mut mem: Vec<u8> = vec![0; crate::compile::MEM_SZ as usize + crate::compile::STRING_SZ as usize];
@@ -25,7 +25,7 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
// }
while ti < tokens.len() {
let token = &tokens[ti];
let pos = token.pos.clone();
let pos = token.loc.clone();
// println!("{:?}", token.typ);
match token.typ {
@@ -272,5 +272,5 @@ pub fn run(tokens: Vec<crate::constants::Operator>) -> Result<()>{
}
Ok(())
Ok(0)
}

View File

@@ -44,6 +44,8 @@ fn lex_line(text: String) -> Result<Vec<(u32, String, TokenType)>> {
let t = t.replace("\\n", "\n")
.replace("\\t", "\t")
.replace("\\r", "\r")
.replace("\\\'", "\'")
.replace("\\\"", "\"")
.replace("\\0", "\0");
if !t.is_empty() {
tokens.push((col, t.to_string(), TokenType::String));
@@ -100,5 +102,6 @@ pub fn lex(code: String, file: &String, args: Args, preprocessing: bool) -> Resu
if preprocessing {
tokens = preprocess(tokens, args)?;
}
Ok(tokens)
}

View File

@@ -72,10 +72,7 @@ fn main() -> Result<()> {
}
};
// for token in &tokens {
// println!("(f: {}, l: {}, c: {}, t: {})", token.file, token.line, token.col, token.text);
// }
let mut parser = parser::Parser::new(tokens);
let tokens = match parser.parse() {
Ok(t) => t,
@@ -84,26 +81,29 @@ fn main() -> Result<()> {
return Ok(());
}
};
if args.compile && args.interpret {
let c = if args.compile && args.interpret {
error!("Cannot compile and interpret at the same time");
0
} else if args.interpret {
match interpret::linux_x86_64::run(tokens) {
Ok(_) => (),
Ok(c) => c,
Err(_) => {
error!("Interpretation failed, exiting!");
return Ok(());
1
}
};
}
} else if args.compile {
match compile::linux_x86_64::compile(tokens, args) {
Ok(_) => (),
Ok(c) => c,
Err(_) => {
error!("Compilation failed, exiting!");
return Ok(());
1
}
};
}
} else {
error!("Did not choose to compile or to interpret, exiting");
}
Ok(())
0
};
std::process::exit(c);
}

View File

@@ -15,7 +15,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
OpType::Else => {
let if_ip = stack.pop().unwrap();
if program[if_ip as usize].typ != OpType::If {
lerror!(&op.clone().pos,"'end' can only close 'if' blocks");
lerror!(&op.clone().loc,"'end' can only close 'if' blocks");
return Err(eyre!("Bad block"));
}
@@ -37,7 +37,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
program[ip].jmp = program[block_ip as usize].jmp;
program[block_ip as usize].jmp = (ip + 1) as i32;
} else {
lerror!(&op.clone().pos,"'end' can only close 'if' blocks");
lerror!(&op.clone().loc,"'end' can only close 'if' blocks");
return Err(eyre!(""));
}
@@ -55,7 +55,7 @@ pub fn cross_ref(mut program: Vec<Operator>) -> Result<Vec<Operator>> {
}
if stack.len() > 0 {
lerror!(&program[stack.pop().expect("Empy stack") as usize].clone().pos,"Unclosed block");
lerror!(&program[stack.pop().expect("Empy stack") as usize].clone().loc,"Unclosed block");
return Err(eyre!("Unclosed block"));
}
@@ -83,7 +83,7 @@ impl Parser {
let pos = (token.file.clone(), token.line, token.col);
match token.typ {
TokenType::Word => {
let word_type = lookup_word(token.text.clone(), &pos)?;
let word_type = lookup_word(token.text.clone(), &pos);
tokens.push(Operator::new(word_type, 0, token.text.clone(), token.file.clone(), token.line, token.col));
},
TokenType::Int => {// negative numbers not yet implemented
@@ -103,7 +103,7 @@ impl Parser {
}
pub fn lookup_word<P: Deref<Target = (String, u32, u32)>>(s: String, _pos: P) -> Result<OpType>{
pub fn lookup_word<P: Deref<Target = (String, u32, u32)>>(s: String, _pos: P) -> OpType {
let lookup_table: HashMap<&str, OpType> = HashMap::from([
//stack
("print", OpType::Print),
@@ -151,9 +151,9 @@ pub fn lookup_word<P: Deref<Target = (String, u32, u32)>>(s: String, _pos: P) ->
]);
match lookup_table.get(s.as_str()) {
Some(v) => Ok(v.clone()),
Some(v) => v.clone(),
None => {
Ok(OpType::None)
OpType::None
}
}
}

View File

@@ -6,7 +6,7 @@ use eyre::eyre;
use crate::constants::{Token, Loc, OpType, TokenType};
use crate::lexer::lex;
use crate::{lerror, lnote, Args};
use crate::{lerror, lnote, Args, warn};
use crate::parser::lookup_word;
#[derive(Debug)]
@@ -24,7 +24,7 @@ pub fn preprocess(tokens: Vec<Token>, args: Args) -> Result<Vec<Token>>{
while rtokens.len() > 0 {
let token = rtokens.pop().unwrap();
let op_type = lookup_word(token.text.clone(), &token.loc())?;
let op_type = lookup_word(token.text.clone(), &token.loc());
match token.clone() {
_ if op_type == OpType::Macro => {
if rtokens.len() == 0 {
@@ -37,17 +37,19 @@ pub fn preprocess(tokens: Vec<Token>, args: Args) -> Result<Vec<Token>>{
lerror!(&macro_name.loc(), "Bad macro name, expected {} but found {}", TokenType::Word.human(), macro_name.typ.human());
return Err(eyre!(""));
}
let word = lookup_word(macro_name.text.clone(), &macro_name.loc())?;
let word = lookup_word(macro_name.text.clone(), &macro_name.loc());
if word != OpType::None {
lerror!(&macro_name.loc(), "Macro name cannot be a built in word, got '{}'", word.human());
return Err(eyre!(""));
}
if crate::constants::ALLOW_MACRO_REDEFINITION {
if macros.get(&macro_name.text.clone()).is_some() {
if macros.get(&macro_name.text.clone()).is_some() {
if crate::constants::ALLOW_MACRO_REDEFINITION {
lerror!(&macro_name.loc(), "Macro redefinition is not allowed");
lnote!(&macros.get(&macro_name.text.clone()).unwrap().loc, "First definition here");
return Err(eyre!(""));
} else {
//TODO: somehow warn about redefinition of only built in macros
}
}
@@ -56,7 +58,7 @@ pub fn preprocess(tokens: Vec<Token>, args: Args) -> Result<Vec<Token>>{
let mut depth = 0;
while rtokens.len() > 0 {
let t = rtokens.pop().unwrap();
let typ = lookup_word(t.text.clone(), &t.loc())?;
let typ = lookup_word(t.text.clone(), &t.loc());
if typ == OpType::End && depth == 0 {
break;
} else if typ == OpType::End && depth != 0 {
@@ -123,12 +125,31 @@ pub fn preprocess(tokens: Vec<Token>, args: Args) -> Result<Vec<Token>>{
}
}
program = expand_macros(program, macros)?;
//* Feel free to fix this horrifying shit
//* i wanna kms
let mut times = 0;
while program.iter().map(|f| {
if f.typ == TokenType::Word {
lookup_word(f.text.clone(), &f.loc())
} else {
OpType::PushInt // i hate myself, this is a randomly picked optype so its happy and works
}
}).collect::<Vec<OpType>>().contains(&OpType::None){
if times >= 50 {
warn!("File import depth maxed out, if the program crashes try reducing the import depth, good luck youll need it");
break
}
program = expand_macros(program, &macros)?;
times += 1;
}
Ok(program)
}
pub fn expand_macros(tokens: Vec<Token>, macros: HashMap<String, Macro>) -> Result<Vec<Token>> {
pub fn expand_macros(tokens: Vec<Token>, macros: &HashMap<String, Macro>) -> Result<Vec<Token>> {
let mut program: Vec<Token> = Vec::new();
let mut rtokens = tokens.clone();
@@ -136,7 +157,7 @@ pub fn expand_macros(tokens: Vec<Token>, macros: HashMap<String, Macro>) -> Resu
while rtokens.len() > 0 {
let op = rtokens.pop().unwrap();
let op_type = lookup_word(op.text.clone(), &op.loc())?;
let op_type = lookup_word(op.text.clone(), &op.loc());
if op.typ == TokenType::Word {
match op_type {
OpType::None => {