finally working again

This commit is contained in:
MCorange 2023-03-13 02:00:26 +02:00
parent cfcea89dac
commit 0921100d4f
16 changed files with 213 additions and 163 deletions

BIN
a

Binary file not shown.

33
a.nasm
View File

@ -1,14 +1,16 @@
global _start global _start
segment .text segment .text
print: print:
mov r8, -3689348814741910323 mov r9, -3689348814741910323
sub rsp, 40 sub rsp, 40
mov BYTE [rsp+32], 10 mov BYTE [rsp+31], 10
lea rcx, [rsp+31] lea rcx, [rsp+30]
.L2: .L2:
mov rax, rdi mov rax, rdi
mul r8 lea r8, [rsp+32]
mul r9
mov rax, rdi mov rax, rdi
sub r8, rcx
shr rdx, 3 shr rdx, 3
lea rsi, [rdx+rdx*4] lea rsi, [rdx+rdx*4]
add rsi, rsi add rsi, rsi
@ -21,13 +23,12 @@ segment .text
sub rcx, 1 sub rcx, 1
cmp rax, 9 cmp rax, 9
ja .L2 ja .L2
lea rcx, [rsp+32]
lea rax, [rsp+32] lea rax, [rsp+32]
mov edi, 1 mov edi, 1
sub rax, rdx sub rdx, rax
sub rdx, rcx xor eax, eax
lea rsi, [rsp+32+rdx] lea rsi, [rsp+32+rdx]
mov rdx, rax mov rdx, r8
mov rax, 1 mov rax, 1
syscall syscall
add rsp, 40 add rsp, 40
@ -47,6 +48,20 @@ _start:
; -- PRINT ; -- PRINT
pop rdi pop rdi
call print call print
; -- PUSH 500
mov rax, 500
push rax
; -- PUSH 80
mov rax, 80
push rax
; -- MINUS
pop rax
pop rbx
sub rbx, rax
push rbx
; -- PRINT
pop rdi
call print
mov rax, 60 mov rax, 60
mov rdi, 0 mov rdi, 0
syscall syscall

BIN
a.o

Binary file not shown.

View File

@ -1,7 +1,7 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::process::{Command, Stdio}; use std::process::{Command, Stdio};
use color_eyre::Result; use color_eyre::Result;
use crate::compile::logger; use crate::util::logger;
pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf) -> Result<()> { pub fn linux_x86_64_compile_and_link(of_a: PathBuf, of_o: PathBuf, of_c: PathBuf) -> Result<()> {

View File

@ -1,9 +1,8 @@
use std::{fs, path::PathBuf, io::{Write, BufWriter}}; use std::{fs, path::PathBuf, io::{Write, BufWriter}};
use crate::{constants::{Operator, OpType}, Args}; use crate::{constants::{Operator, OpType}, Args};
use color_eyre::Result; use color_eyre::Result;
use crate::compile::commands; use crate::compile::commands::linux_x86_64_compile_and_link;
use super::commands::linux_x86_64_compile_and_link;
pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
let mut of_c = PathBuf::from(&args.out_file); let mut of_c = PathBuf::from(&args.out_file);
@ -20,15 +19,17 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, "global _start")?; writeln!(writer, "global _start")?;
writeln!(writer, "segment .text")?; writeln!(writer, "segment .text")?;
writeln!(writer, " print:")?; writeln!(writer, "print:")?;
writeln!(writer, " mov r8, -3689348814741910323")?; writeln!(writer, " mov r9, -3689348814741910323")?;
writeln!(writer, " sub rsp, 40")?; writeln!(writer, " sub rsp, 40")?;
writeln!(writer, " mov BYTE [rsp+32], 10")?; writeln!(writer, " mov BYTE [rsp+31], 10")?;
writeln!(writer, " lea rcx, [rsp+31]")?; writeln!(writer, " lea rcx, [rsp+30]")?;
writeln!(writer, ".L2:")?; writeln!(writer, ".L2:")?;
writeln!(writer, " mov rax, rdi")?; writeln!(writer, " mov rax, rdi")?;
writeln!(writer, " mul r8")?; writeln!(writer, " lea r8, [rsp+32]")?;
writeln!(writer, " mul r9")?;
writeln!(writer, " mov rax, rdi")?; writeln!(writer, " mov rax, rdi")?;
writeln!(writer, " sub r8, rcx")?;
writeln!(writer, " shr rdx, 3")?; writeln!(writer, " shr rdx, 3")?;
writeln!(writer, " lea rsi, [rdx+rdx*4]")?; writeln!(writer, " lea rsi, [rdx+rdx*4]")?;
writeln!(writer, " add rsi, rsi")?; writeln!(writer, " add rsi, rsi")?;
@ -41,13 +42,12 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " sub rcx, 1")?; writeln!(writer, " sub rcx, 1")?;
writeln!(writer, " cmp rax, 9")?; writeln!(writer, " cmp rax, 9")?;
writeln!(writer, " ja .L2")?; writeln!(writer, " ja .L2")?;
writeln!(writer, " lea rcx, [rsp+32]")?;
writeln!(writer, " lea rax, [rsp+32]")?; writeln!(writer, " lea rax, [rsp+32]")?;
writeln!(writer, " mov edi, 1")?; writeln!(writer, " mov edi, 1")?;
writeln!(writer, " sub rax, rdx")?; writeln!(writer, " sub rdx, rax")?;
writeln!(writer, " sub rdx, rcx")?; writeln!(writer, " xor eax, eax")?;
writeln!(writer, " lea rsi, [rsp+32+rdx]")?; writeln!(writer, " lea rsi, [rsp+32+rdx]")?;
writeln!(writer, " mov rdx, rax")?; writeln!(writer, " mov rdx, r8")?;
writeln!(writer, " mov rax, 1")?; writeln!(writer, " mov rax, 1")?;
writeln!(writer, " syscall")?; writeln!(writer, " syscall")?;
writeln!(writer, " add rsp, 40")?; writeln!(writer, " add rsp, 40")?;
@ -79,7 +79,7 @@ pub fn compile(tokens: Vec<Operator>, args: Args) -> Result<()>{
writeln!(writer, " pop rax")?; writeln!(writer, " pop rax")?;
writeln!(writer, " pop rbx")?; writeln!(writer, " pop rbx")?;
writeln!(writer, " sub rbx, rax")?; writeln!(writer, " sub rbx, rax")?;
writeln!(writer, " push rax")?; writeln!(writer, " push rbx")?;
}, },
OpType::Print => { OpType::Print => {
writeln!(writer, " ; -- PRINT")?; writeln!(writer, " ; -- PRINT")?;

View File

@ -1,9 +0,0 @@
use crate::util::color;
pub fn error(msg: &str) {
eprintln!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET);
}
pub fn info(msg: &str) {
println!("{green}info{r}: {msg}", green=color::FG_GREEN, r=color::RESET);
}

View File

@ -1,4 +1,3 @@
pub mod linux_x86_64; pub mod linux_x86_64;
pub mod commands; pub mod commands;
pub mod logger;

View File

@ -24,9 +24,10 @@ impl Operator {
} }
#[derive(Debug)]
pub struct Token { pub struct Token {
file: String, pub file: String,
line: u32, pub line: u32,
col: u32, pub col: u32,
text: String pub text: String
} }

View File

@ -1,9 +1,8 @@
use crate::constants::OpType; use crate::constants::OpType;
use crate::interpret::logger; // use crate::util::logger;
use std::io::{self, Write};
use color_eyre::Result; use color_eyre::Result;
fn stack_pop(mut stack: &mut Vec<i32>) -> Result<i32, &'static str> { fn stack_pop(stack: &mut Vec<i32>) -> Result<i32, &'static str> {
match stack.pop() { match stack.pop() {
Some(i) => Ok(i), Some(i) => Ok(i),
None => Err("Stack underflow"), None => Err("Stack underflow"),

View File

@ -1,5 +0,0 @@
use crate::util::color;
pub fn error(msg: &str) {
println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET);
}

View File

@ -1,2 +1 @@
pub mod linux_x86_64; pub mod linux_x86_64;
mod logger;

View File

@ -1,27 +1,49 @@
use crate::constants::Token; use crate::constants::Token;
use color_eyre::Result; use color_eyre::Result;
use crate::util::StringExtra;
pub fn strip_col(text: String, mut col: u32) -> Result<u32> { pub fn find_col<F>(text: String, mut col: u32, predicate: F) -> Result<u32> where F: Fn(char) -> bool {
while (col as usize) < text.len() && text.chars().nth(col as usize).unwrap().is_whitespace() { while (col as usize) < text.len() && !predicate(text.chars().nth(col as usize).unwrap()) {
col += 1; col += 1;
} }
Ok(32) Ok(col)
} }
pub fn lex(code: String) -> Result<Vec<Token>> {
fn lex_line(text: String) -> Result<Vec<(u32, String)>> {
let mut tokens: Vec<(u32, String)> = Vec::new();
let mut col = find_col(text.clone(), 0, |x| !x.is_whitespace())?;
let mut col_end: u32 = 0;
while col_end < text.clone().len() as u32 {
col_end = find_col(text.clone(), col, |x| x.is_whitespace())?;
let t = &text[(col as usize)..((col_end as usize))];
tokens.push((col, t.to_string()));
col = find_col(text.clone(), col_end, |x| !x.is_whitespace())?;
}
Ok(tokens)
}
pub fn lex(code: String, file: &String) -> Result<Vec<Token>> {
let lines: Vec<(usize, &str)> = code.split(['\n', '\r']).enumerate().collect(); let lines: Vec<(usize, &str)> = code.split(['\n', '\r']).enumerate().collect();
let lines: Vec<(u32, String)> = lines.iter().map(|i| (i.0 as u32, i.1.to_string())).collect(); let lines: Vec<(u32, String)> = lines.iter().map(|i| (i.0 as u32, i.1.to_string())).collect();
let mut tokens: Vec<Token> = Vec::new(); let mut tokens: Vec<Token> = Vec::new();
let mut col = strip_col(code, 0)?; for (row, line) in lines {
let lt = lex_line(line)?;
for line in lines { for (col, tok) in lt {
let col_end = code.find_idx(' ', col); let t = Token{
col = strip_col(code, 0)?; file: file.clone(),
line: row + 1,
col: col,
text: tok,
};
tokens.push(t);
}
} }
Ok(tokens) Ok(tokens)

View File

@ -30,11 +30,6 @@ pub struct Args {
interpret: bool interpret: bool
} }
use constants::{
OpType,
Operator
};
fn main() -> Result<(), &'static str> { fn main() -> Result<(), &'static str> {
let args = Args::parse(); let args = Args::parse();
@ -42,10 +37,13 @@ fn main() -> Result<(), &'static str> {
let code = fs::read_to_string(&args.in_file).unwrap(); let code = fs::read_to_string(&args.in_file).unwrap();
let tokens = lexer::lex(code); let tokens = lexer::lex(code, &args.in_file).unwrap();
dbg!(tokens);
return Ok(()); // for token in &tokens {
let mut parser = parser::Parser::new(code.clone()); // println!("(f: {}, l: {}, c: {}, t: {})", token.file, token.line, token.col, token.text);
// }
let mut parser = parser::Parser::new(tokens);
let tokens = parser.parse()?; let tokens = parser.parse()?;
if args.compile && args.interpret { if args.compile && args.interpret {
util::logger::error("Cannot compile and interpret at the same time"); util::logger::error("Cannot compile and interpret at the same time");

View File

@ -1,27 +1,24 @@
use crate::{constants::{Operator, OpType}, util}; use crate::{constants::{Operator, OpType, Token}, util};
use color_eyre::{Result, Report}; use color_eyre::Result;
pub struct Parser { pub struct Parser {
file: String tokens: Vec<Token>
} }
impl Parser { impl Parser {
pub fn new(file: String) -> Self { pub fn new(file: Vec<Token>) -> Self {
Self{ Self{
file tokens: file
} }
} }
pub fn parse(&mut self) -> Result<Vec<Operator>, &'static str> { pub fn parse(&mut self) -> Result<Vec<Operator>, &'static str> {
let mut tokens = Vec::new(); let mut tokens = Vec::new();
for tok in self.file.split([' ', '\n', '\t', '\r']) { for token in &self.tokens {
if tok == "" { let pos = (token.file.clone(), token.line, token.col);
continue; match token.text.as_str() {
}
match tok {
t if t.parse::<i32>().is_ok() => { t if t.parse::<i32>().is_ok() => {
let num = t.parse::<i32>().unwrap(); let num = t.parse::<i32>().unwrap();
tokens.push(Operator::new(OpType::Push, num)); tokens.push(Operator::new(OpType::Push, num));
@ -34,13 +31,12 @@ impl Parser {
t => { t => {
util::logger::error("Unknown token '{t}'"); util::logger::pos_error(pos, format!("Unknown token '{}'", t).as_str());
return Err(""); return Err("");
} }
} }
} }
dbg!(&tokens);
Ok(tokens) Ok(tokens)
} }
} }

View File

@ -1,53 +1,86 @@
// use color_eyre::Result;
pub mod color { pub mod color {
#[allow(dead_code)] pub const NONE: &str = "\x1b[0m"; #![allow(dead_code)]
#[allow(dead_code)] pub const RESET: &str = "\x1b[0m"; pub const NONE: &str = "\x1b[0m";
#[allow(dead_code)] pub const BRIGHT: &str = "\x1b[1m"; pub const RESET: &str = "\x1b[0m";
#[allow(dead_code)] pub const DIM: &str = "\x1b[2m"; pub const BRIGHT: &str = "\x1b[1m";
#[allow(dead_code)] pub const UNDERSCORE: &str = "\x1b[4m"; pub const DIM: &str = "\x1b[2m";
#[allow(dead_code)] pub const BLINK: &str = "\x1b[5m"; pub const UNDERSCORE: &str = "\x1b[4m";
#[allow(dead_code)] pub const REVERSE: &str = "\x1b[7m"; pub const BLINK: &str = "\x1b[5m";
#[allow(dead_code)] pub const HIDDEN: &str = "\x1b[8m"; pub const REVERSE: &str = "\x1b[7m";
#[allow(dead_code)] pub const FG_BLACK: &str = "\x1b[30m"; pub const HIDDEN: &str = "\x1b[8m";
#[allow(dead_code)] pub const FG_RED: &str = "\x1b[31m"; pub const FG_BLACK: &str = "\x1b[30m";
#[allow(dead_code)] pub const FG_GREEN: &str = "\x1b[32m"; pub const FG_RED: &str = "\x1b[31m";
#[allow(dead_code)] pub const FG_YELLOW: &str = "\x1b[33m"; pub const FG_GREEN: &str = "\x1b[32m";
#[allow(dead_code)] pub const FG_BLUE: &str = "\x1b[34m"; pub const FG_YELLOW: &str = "\x1b[33m";
#[allow(dead_code)] pub const FG_MAGENTA: &str = "\x1b[35m"; pub const FG_BLUE: &str = "\x1b[34m";
#[allow(dead_code)] pub const FG_CYAN: &str = "\x1b[36m"; pub const FG_MAGENTA: &str = "\x1b[35m";
#[allow(dead_code)] pub const FG_WHITE: &str = "\x1b[37m"; pub const FG_CYAN: &str = "\x1b[36m";
#[allow(dead_code)] pub const BG_BLACK: &str = "\x1b[40m"; pub const FG_WHITE: &str = "\x1b[37m";
#[allow(dead_code)] pub const BG_RED: &str = "\x1b[41m"; pub const BG_BLACK: &str = "\x1b[40m";
#[allow(dead_code)] pub const BG_GREEN: &str = "\x1b[42m"; pub const BG_RED: &str = "\x1b[41m";
#[allow(dead_code)] pub const BG_YELLOW: &str = "\x1b[43m"; pub const BG_GREEN: &str = "\x1b[42m";
#[allow(dead_code)] pub const BG_BLUE: &str = "\x1b[44m"; pub const BG_YELLOW: &str = "\x1b[43m";
#[allow(dead_code)] pub const BG_MAGENTA: &str = "\x1b[45m"; pub const BG_BLUE: &str = "\x1b[44m";
#[allow(dead_code)] pub const BG_CYAN: &str = "\x1b[46m"; pub const BG_MAGENTA: &str = "\x1b[45m";
#[allow(dead_code)] pub const BG_WHITE: &str = "\x1b[47m"; pub const BG_CYAN: &str = "\x1b[46m";
pub const BG_WHITE: &str = "\x1b[47m";
} }
pub mod logger { pub mod logger {
#![allow(dead_code)]
use crate::util::color; use crate::util::color;
pub fn error(msg: &str) { pub fn error(msg: &str) {
println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET); println!("{red}error{r}: {msg}", red=color::FG_RED, r=color::RESET);
} }
pub fn warn(msg: &str) {
println!("{yellow}warn{r}: {msg}", yellow=color::FG_YELLOW, r=color::RESET);
}
pub fn info(msg: &str) {
println!("{green}info{r}: {msg}", green=color::FG_GREEN, r=color::RESET);
}
pub fn note(msg: &str) {
println!("{blue}note{r}: {msg}", blue=color::FG_BLUE, r=color::RESET);
}
pub fn pos_error(pos: (String, u32, u32), msg: &str) {
println!("{f}:{r}:{c} {red}error{rs}: {msg}", red=color::FG_RED, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2);
}
pub fn pos_warn(pos: (String, u32, u32), msg: &str) {
println!("{f}:{r}:{c} {yellow}warn{rs}: {msg}", yellow=color::FG_YELLOW, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2);
}
pub fn pos_info(pos: (String, u32, u32), msg: &str) {
println!("{f}:{r}:{c} {green}info{rs}: {msg}", green=color::FG_GREEN, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2);
}
pub fn pos_note(pos: (String, u32, u32), msg: &str) {
println!("{f}:{r}:{c} {blue}note{rs}: {msg}", blue=color::FG_BLUE, rs=color::RESET, f=pos.0, r=pos.1, c=pos.2);
}
} }
pub trait StringExtra{ // pub trait StringExtra{
fn find_idx(&self, pat: char, start: u32) -> u32; // fn find_idx(&self, pat: char, start: u32) -> Result<u32, ()>;
} // }
impl StringExtra for String { // impl StringExtra for String {
fn find_idx(&self, pat: char, start: u32) -> u32 { // fn find_idx(&self, pat: char, start: u32) -> Result<u32, ()> {
let mut col = start; // let mut col = start;
for c in self.chars() { // for c in (*self).chars() {
if c == pat { // if c == pat {
break; // return Ok(col);
} // }
col += 1; // col += 1;
} // }
col // Err(())
} // }
} // }

View File

@ -1 +1,3 @@
35 34 + print 35 34 + print
500 80 - print