Still incredibly buggy, but i need to commit something to git.
I'm going to fix the problem soon trust me :3
This commit is contained in:
parent
fba9dded42
commit
7d7bac18c6
|
@ -1,19 +1,33 @@
|
|||
use std::rc::Rc;
|
||||
use crate::parse::ast::*;
|
||||
use skylang::temp;
|
||||
use std::rc::Rc;
|
||||
|
||||
const REGISTERS: [&str; 9] = ["r10", "r11", "r12", "r13", "r14", "r15", "rax", "rdi", "rsi"];
|
||||
|
||||
const REGISTERS: [&str; 9] = ["r10", "r11", "r12", "r13", "r14", "rsp", "rbp", "rdp", "rdi"];
|
||||
#[derive(Debug)]
|
||||
pub struct FasmCodegen {
|
||||
register_counter: usize,
|
||||
operation_queue: Vec<String>
|
||||
operation_queue: Vec<OperationQueue>,
|
||||
use_queue: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum OperationQueue {
|
||||
RegisterCounter(usize),
|
||||
Instruction(String),
|
||||
}
|
||||
|
||||
impl Default for FasmCodegen {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl FasmCodegen {
|
||||
pub fn new() -> Self {
|
||||
FasmCodegen {
|
||||
register_counter: 0,
|
||||
operation_queue: Vec::new()
|
||||
operation_queue: Vec::new(),
|
||||
use_queue: false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,7 +42,7 @@ impl FasmCodegen {
|
|||
self.fasm_codegen($exprs, false)
|
||||
}};
|
||||
}
|
||||
|
||||
|
||||
// Define asm_func, used for functions.
|
||||
let mut asm_func = String::new();
|
||||
// Define asm_data, used for variables.
|
||||
|
@ -57,28 +71,45 @@ impl FasmCodegen {
|
|||
match expr {
|
||||
// If the expression is a math expression.
|
||||
Expr::MathExpr(e) => {
|
||||
if let Expr::MathExpr(m) = e.right.as_ref() {
|
||||
let codegen = fasm_codegen!(fun: &vec![Expr::MathExpr(m.clone())]);
|
||||
self.operation_queue.push(codegen);
|
||||
if let Expr::MathExpr(_m) = e.right.as_ref() {
|
||||
self.register_counter += 1;
|
||||
|
||||
self.operation_queue.push(OperationQueue::RegisterCounter(self.register_counter));
|
||||
self.use_queue = true;
|
||||
} else {
|
||||
self.use_queue = false;
|
||||
}
|
||||
let mut register_counter = Box::new(self.register_counter);
|
||||
if self.use_queue {
|
||||
println!("self.use_queue");
|
||||
if let Some(OperationQueue::RegisterCounter(q)) = self.operation_queue.pop() {
|
||||
register_counter = Box::new(q);
|
||||
}
|
||||
}
|
||||
dbg!(*register_counter, self.register_counter, self.use_queue);
|
||||
unwrap!(e.left);
|
||||
self.register_counter += 1;
|
||||
asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[self.register_counter]).as_str());
|
||||
dbg!(*register_counter, self.register_counter, self.use_queue);
|
||||
asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[*register_counter]).as_str());
|
||||
unwrap!(e.right);
|
||||
self.register_counter += 1;
|
||||
asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[self.register_counter]).as_str());
|
||||
dbg!(*register_counter, self.register_counter, self.use_queue);
|
||||
asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[*register_counter]).as_str());
|
||||
self.register_counter += 1;
|
||||
match e.operator {
|
||||
// If the operator is addition.
|
||||
MathOperator::OP_ADD => {
|
||||
asm_start.push_str(format!("\tadd {}, {}\n", REGISTERS[self.register_counter - 1], REGISTERS[self.register_counter]).as_str());
|
||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[self.register_counter - 1]).as_str());
|
||||
asm_start.push_str(format!("\tadd {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str());
|
||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str());
|
||||
|
||||
// r10 ← r10 + r11; rax ← r10;
|
||||
// The sum will now be stored in the %rax register.
|
||||
},
|
||||
// If the operator is multiplication.
|
||||
MathOperator::OP_MULT => {
|
||||
asm_start.push_str(format!("\timul {}, {}\n", REGISTERS[self.register_counter - 1], REGISTERS[self.register_counter]).as_str());
|
||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[self.register_counter - 1]).as_str());
|
||||
asm_start.push_str(format!("\timul {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str());
|
||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str());
|
||||
|
||||
// r10 ← r10 * r11; rax ← r10;
|
||||
// The product will now be stored in the %rax register.
|
||||
},
|
||||
|
@ -94,6 +125,7 @@ impl FasmCodegen {
|
|||
MathOperator::OP_SUB => {
|
||||
asm_start.push_str("\tsub r10, r11\n");
|
||||
asm_start.push_str("\tmov rax, r10\n");
|
||||
|
||||
// r10 ← r10 - r11; rax ← r10;
|
||||
// The difference will now be stored in the %rax register.
|
||||
},
|
||||
|
@ -116,49 +148,49 @@ impl FasmCodegen {
|
|||
0 => {
|
||||
// First parameter. Put in %rdi.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov rdi, rax\n").as_str());
|
||||
asm_start.push_str("\tmov rdi, rax\n".to_string().as_str());
|
||||
// rdi ← e.params[0];
|
||||
},
|
||||
|
||||
1 => {
|
||||
// Second parameter. Put in %rsi.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov rsi, rax\n").as_str());
|
||||
asm_start.push_str("\tmov rsi, rax\n".to_string().as_str());
|
||||
// rsi ← e.params[1];
|
||||
},
|
||||
|
||||
2 => {
|
||||
// Third parameter. Put in %rdx.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov rdx, rax\n").as_str());
|
||||
asm_start.push_str("\tmov rdx, rax\n".to_string().as_str());
|
||||
// rdx ← e.params[2];
|
||||
},
|
||||
|
||||
3 => {
|
||||
// Fourth parameter. Put in %rcx.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov rcx, rax\n").as_str());
|
||||
asm_start.push_str("\tmov rcx, rax\n".to_string().as_str());
|
||||
// rcx ← e.params[3];
|
||||
},
|
||||
|
||||
4 => {
|
||||
// Fifth parameter. Put in %r8.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov r8, rax").as_str());
|
||||
asm_start.push_str("\tmov r8, rax".to_string().as_str());
|
||||
// r8 ← e.params[4];
|
||||
},
|
||||
|
||||
5 => {
|
||||
// Sixth parameter. Put in %r9.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tmov r9, rax\n").as_str());
|
||||
asm_start.push_str("\tmov r9, rax\n".to_string().as_str());
|
||||
// r9 ← e.params[5];
|
||||
},
|
||||
|
||||
_ => {
|
||||
// Parameters after the sixth parameter are pushed to the stack.
|
||||
unwrap!(p);
|
||||
asm_start.push_str(format!("\tpush rax\n").as_str());
|
||||
asm_start.push_str("\tpush rax\n".to_string().as_str());
|
||||
// STACK_TOP ← e.params[(6+)];
|
||||
}
|
||||
}
|
||||
|
@ -206,7 +238,7 @@ impl FasmCodegen {
|
|||
asm_start.push_str("mov rdi, rax");
|
||||
unwrap!(e.right);
|
||||
asm_start.push_str("mov rsi, rax");
|
||||
asm_start.push_str(format!("\tcmp rdi, rsi\n").as_str());
|
||||
asm_start.push_str("\tcmp rdi, rsi\n".to_string().as_str());
|
||||
// Check what the condition is.
|
||||
match e.cond {
|
||||
COND_OP::EQ => {
|
||||
|
@ -232,7 +264,7 @@ impl FasmCodegen {
|
|||
no => unsafe {
|
||||
// Write some data I randomly typed to your memory because don't going around playing with something that I haven't implemented yet.
|
||||
println!("{:?} is not. implemented.", no);
|
||||
let mut ptr = 0x00 as *mut f64;
|
||||
let ptr = std::ptr::null_mut::<f64>();
|
||||
::std::ptr::write(ptr, 124010240120401240.12410240124120401240);
|
||||
},
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
pub mod tok;
|
|
@ -1,149 +0,0 @@
|
|||
#![allow(unused)]
|
||||
|
||||
use super::tok::*;
|
||||
|
||||
|
||||
fn check_single_char<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
let tok = match word {
|
||||
";" => tok!(Semicolon),
|
||||
"=" => tok!(Equal),
|
||||
"(" => tok!(LeftParen),
|
||||
")" => tok!(RightParen),
|
||||
"{" => tok!(LeftBrace),
|
||||
"}" => tok!(RightBrace),
|
||||
"," => tok!(Comma),
|
||||
"." => tok!(Dot),
|
||||
"-" => tok!(Minus),
|
||||
"+" => tok!(Plus),
|
||||
"/" => tok!(Slash),
|
||||
"*" => tok!(Star),
|
||||
"%" => tok!(Percent),
|
||||
"!" => tok!(Bang),
|
||||
":" => tok!(Colon),
|
||||
"<" => tok!(Less),
|
||||
">" => tok!(Greater),
|
||||
|
||||
_ => None
|
||||
};
|
||||
|
||||
tok
|
||||
}
|
||||
|
||||
fn check_keyword<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
let tok = match word {
|
||||
"fn" => tok!(Fn),
|
||||
"let" => tok!(Let),
|
||||
"if" => tok!(If),
|
||||
"else" => tok!(Else),
|
||||
"while" => tok!(While),
|
||||
"elif" => tok!(Elif),
|
||||
"return" => tok!(Return),
|
||||
"for" => tok!(For),
|
||||
"in" => tok!(In),
|
||||
"break" => tok!(Break),
|
||||
"continue" => tok!(Continue),
|
||||
"true" => tok!(True),
|
||||
"false" => tok!(False),
|
||||
|
||||
_ => None
|
||||
};
|
||||
|
||||
tok
|
||||
}
|
||||
|
||||
fn check_two_char<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
let tok = match word {
|
||||
"==" => tok!(EqualEqual),
|
||||
"!=" => tok!(BangEqual),
|
||||
"<=" => tok!(LessEqual),
|
||||
">=" => tok!(GreaterEqual),
|
||||
|
||||
_ => None
|
||||
};
|
||||
|
||||
tok
|
||||
}
|
||||
|
||||
fn match_string_literal<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
let chars = word.chars();
|
||||
|
||||
if word.starts_with("\"") {
|
||||
while let Some(char) = chars.next() {
|
||||
if char == '\"' {
|
||||
return tok!(String);
|
||||
}
|
||||
}
|
||||
}
|
||||
if word.starts_with("\'") {
|
||||
while let Some(char) = chars.next() {
|
||||
if char == '\'' {
|
||||
return tok!(String);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn match_int_literal<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
let chars = word.chars();
|
||||
|
||||
while let Some(char) = chars.next() {
|
||||
if char.is_digit(10) {
|
||||
return tok!(Number);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn match_identifier<'a>(word: &'a str) -> Option<Token<'a>> {
|
||||
macro_rules! tok {
|
||||
($tt:expr) => {
|
||||
Some(Token::new($tt, word))
|
||||
};
|
||||
};
|
||||
|
||||
let chars = word.chars();
|
||||
|
||||
if chars.next().is_ascii_alphabetic() {
|
||||
while let Some(char) = chars.next() {
|
||||
if chars.next().is_ascii() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -106,3 +106,51 @@ pub fn lex_str(this: &str) -> Vec<(Token, &str)> {
|
|||
|
||||
buf
|
||||
}
|
||||
|
||||
|
||||
impl std::fmt::Display for Token {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Semicolon => write!(f, ";"),
|
||||
Equal => write!(f, "="),
|
||||
LeftParen => write!(f, "("),
|
||||
RightParen => write!(f, ")"),
|
||||
LeftBrace => write!(f, "{{"),
|
||||
RightBrace => write!(f, "}}"),
|
||||
Comma => write!(f, ","),
|
||||
Dot => write!(f, "."),
|
||||
Minus => write!(f, "-"),
|
||||
Plus => write!(f, "+"),
|
||||
Slash => write!(f, "/"),
|
||||
Star => write!(f, "*"),
|
||||
Percent => write!(f, "%"),
|
||||
Bang => write!(f, "!"),
|
||||
Colon => write!(f, ":"),
|
||||
Less => write!(f, "<"),
|
||||
Greater => write!(f, ">"),
|
||||
Pipe => write!(f, "|"),
|
||||
Fnaf => write!(f, "fnaf"),
|
||||
Let => write!(f, "let"),
|
||||
Global => write!(f, "global"),
|
||||
If => write!(f, "if"),
|
||||
Else => write!(f, "else"),
|
||||
While => write!(f, "while"),
|
||||
Elif => write!(f, "elif"),
|
||||
Return => write!(f, "return"),
|
||||
For => write!(f, "for"),
|
||||
In => write!(f, "in"),
|
||||
Break => write!(f, "break"),
|
||||
Continue => write!(f, "continue"),
|
||||
EqualEqual => write!(f, "=="),
|
||||
BangEqual => write!(f, "!="),
|
||||
LessEqual => write!(f, "<="),
|
||||
GreaterEqual => write!(f, ">="),
|
||||
String => write!(f, "[string]"),
|
||||
Number(n) => write!(f, "{}", n),
|
||||
Identifier => write!(f, "identifier"),
|
||||
True => write!(f, "true"),
|
||||
False => write!(f, "false"),
|
||||
Null => write!(f, "none"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
124
src/lex/tok.rs~
124
src/lex/tok.rs~
|
@ -1,124 +0,0 @@
|
|||
#![allow(unused)]
|
||||
pub use TokenType::*;
|
||||
use super::parse::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Token<'a> {
|
||||
tt: TokenType,
|
||||
word: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TokenType {
|
||||
EOF,
|
||||
|
||||
// SINGLE CHARACTER TOKENS
|
||||
Semicolon, // ;
|
||||
Equal, // =
|
||||
LeftParen, // (
|
||||
RightParen, // )
|
||||
LeftBrace, // {
|
||||
RightBrace, // }
|
||||
Comma, // ,
|
||||
Dot, // .
|
||||
Minus, // -
|
||||
Plus, // +
|
||||
Slash, // /
|
||||
Star, // *
|
||||
Percent, // %
|
||||
Bang, // !
|
||||
Colon, // :
|
||||
Less, // <
|
||||
Greater, // >
|
||||
|
||||
// KEYWORDS
|
||||
Fn, // fn
|
||||
Let, // let
|
||||
If, // if
|
||||
Else, // else
|
||||
While, // while
|
||||
Elif, // elif
|
||||
Return, // return
|
||||
For, // for
|
||||
In, // in
|
||||
Break, // break
|
||||
Continue, // continue
|
||||
|
||||
// TWO CHARACTER TOKENS
|
||||
EqualEqual, // ==
|
||||
BangEqual, // !=
|
||||
LessEqual, // <=
|
||||
GreaterEqual, // >=
|
||||
|
||||
// LITERALS
|
||||
String, // A string literal.
|
||||
Number, // An integer.
|
||||
Identifier, // An identifier.
|
||||
True, // true
|
||||
False, // false
|
||||
Null, // None
|
||||
|
||||
// ERROR
|
||||
Error, // A syntax error.
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Lexer<'a> {
|
||||
source: &'a str,
|
||||
tokens: Vec<Token<'a>>,
|
||||
current: usize,
|
||||
after: &'a str
|
||||
}
|
||||
|
||||
impl<'a> Lexer<'a> {
|
||||
pub fn new() -> Self {
|
||||
Lexer {
|
||||
source: "",
|
||||
tokens: Vec::new(),
|
||||
current: 0,
|
||||
after: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> std::iter::Iterator for Lexer<'a> {
|
||||
|
||||
}
|
||||
|
||||
impl<'a> From<&'a str> for Lexer<'a> {
|
||||
fn from(value: &'a str) -> Self {
|
||||
Lexer {
|
||||
source: value,
|
||||
tokens: Vec::new(),
|
||||
current: 0,
|
||||
after: value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a std::string::String> for Lexer<'a> {
|
||||
fn from(value: &'a std::string::String) -> Self {
|
||||
Lexer {
|
||||
source: value.as_str(),
|
||||
tokens: Vec::new(),
|
||||
current: 0,
|
||||
after: value.as_str()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Token<'a> {
|
||||
pub fn new(tt: TokenType, word: &'a str) -> Self {
|
||||
Token {
|
||||
tt,
|
||||
word
|
||||
}
|
||||
}
|
||||
|
||||
pub fn empty() -> Self {
|
||||
Token {
|
||||
tt: EOF,
|
||||
word: ""
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
#![feature(associated_type_bounds)]
|
||||
#![allow(warnings)]
|
||||
|
||||
pub mod lex;
|
||||
pub mod codegen;
|
||||
use crate::codegen::fasm::*;
|
||||
use crate::lex::tok::*;
|
||||
use crate::parse::ast::*;
|
||||
|
||||
use crate::parse::parse::*;
|
||||
use logos::Logos;
|
||||
|
||||
|
@ -54,7 +52,7 @@ fn main() {
|
|||
// println!("{}", fc);
|
||||
let parsed = "3*10+5";
|
||||
|
||||
let mut lexer = Token::lexer(parsed);
|
||||
let lexer = Token::lexer(parsed);
|
||||
|
||||
println!("\"{}\"", parsed);
|
||||
arrow!(" ");
|
||||
|
@ -63,6 +61,7 @@ fn main() {
|
|||
let parsed = parse_math(lexer);
|
||||
println!("{:?}", parsed);
|
||||
arrow!(" ");
|
||||
println!("{}", FasmCodegen::new().fasm_codegen(&vec![parsed.unwrap()], true));
|
||||
let mut code = FasmCodegen::new();
|
||||
println!("{}", code.fasm_codegen(&vec![parsed.unwrap()], true));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
pub mod lex;
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", lex::parse::match_identifier("goren-"));
|
||||
}
|
|
@ -27,19 +27,17 @@ pub fn parse_math(mut tokens: Lexer<Token>) -> Option<Expr> {
|
|||
|
||||
pub fn parse_global_declaration(mut tokens: Lexer<Token>) -> Option<Expr> {
|
||||
let mut tok = None;
|
||||
if unwrap!(tokens) == Let {
|
||||
if unwrap!(tokens) == Identifier {
|
||||
let name = tokens.slice();
|
||||
if unwrap!(tokens) == Let && unwrap!(tokens) == Identifier {
|
||||
let name = tokens.slice();
|
||||
|
||||
println!("{:?}", name);
|
||||
if unwrap!(tokens) == Equal {
|
||||
let temp_token = unwrap!(tokens);
|
||||
if let Number(n) = temp_token {
|
||||
tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n})));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("{:?}", name);
|
||||
if unwrap!(tokens) == Equal {
|
||||
let temp_token = unwrap!(tokens);
|
||||
if let Number(n) = temp_token {
|
||||
tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n})));
|
||||
}
|
||||
}
|
||||
}
|
||||
tok
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue