Made the backend compile and be more recursive :3.
This commit is contained in:
parent
db6d6a91a1
commit
b4e60f09e5
|
@ -3,6 +3,9 @@ name = "skylang"
|
|||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::parse::ast::*;
|
||||
use std::rc::Rc;
|
||||
use skylang::temp;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fasm_codegen {
|
||||
|
@ -20,10 +21,9 @@ pub fn fasm_codegen(exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
|||
let mut asm_data = String::new();
|
||||
// Define asm_start, used for the entry point.
|
||||
let mut asm_start = String::new();
|
||||
|
||||
macro_rules! unwrap {
|
||||
($item:expr) => {
|
||||
asm_start.push_str(fasm_codegen!(fun: &vec![*$item.as_ref()]).as_str());
|
||||
asm_start.push_str(fasm_codegen!(fun: &vec![$item.as_ref().clone()]).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,7 @@ pub fn fasm_codegen(exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
|||
asm_start.push_str("_start:\n");
|
||||
asm_data.push_str("\nsegment readable writable\n");
|
||||
}
|
||||
|
||||
|
||||
// Iterate over expressions.
|
||||
for expr in exprs.iter() {
|
||||
// Use patern matching on `expr`.
|
||||
|
@ -46,7 +46,7 @@ pub fn fasm_codegen(exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
|||
unwrap!(e.left);
|
||||
asm_start.push_str(format!("\tmov r10, rax\n").as_str());
|
||||
unwrap!(e.right);
|
||||
asm_start.push_str(format!("\tmov r11, rax").as_str());
|
||||
asm_start.push_str(format!("\tmov r11, rax\n").as_str());
|
||||
match e.operator {
|
||||
// If the operator is addition.
|
||||
MathOperator::OP_ADD => {
|
||||
|
@ -181,31 +181,37 @@ pub fn fasm_codegen(exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
|||
|
||||
Expr::If(e) => {
|
||||
// Increment the temporary variable/function counter.
|
||||
tmp_counter += 1;
|
||||
// Compare the left and right value.
|
||||
|
||||
asm_start.push_str(format!("\tcmp rax, {}\n", e.left, e.right.unwrap()).as_str());
|
||||
unwrap!(e.left);
|
||||
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());
|
||||
// Check what the condition is.
|
||||
match e.cond {
|
||||
COND_OP::EQ => {
|
||||
// If the compared values are equal to each other jump to the temporary function.
|
||||
asm_start.push_str(format!("je .{}", temp(tmp_counter)).as_str());
|
||||
asm_start.push_str(format!("je .{}", temp!()).as_str());
|
||||
},
|
||||
|
||||
COND_OP::NE => {
|
||||
// If the compared values are not equal to eachother jump to the temporary function.
|
||||
asm_start.push_str(format!("jne .{}", temp(tmp_counter)).as_str());
|
||||
asm_start.push_str(format!("jne .{}", temp!()).as_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Create the temporary function.
|
||||
asm_func.push_str(format!(".{}:\n", temp(tmp_counter)).as_str());
|
||||
asm_func.push_str(format!(".{}:\n", temp!()).as_str());
|
||||
asm_func.push_str(fasm_codegen!(fun: &e.action).as_str());
|
||||
asm_func.push_str("\tret\n");
|
||||
|
||||
}
|
||||
_ => unsafe {
|
||||
},
|
||||
Expr::Number(n) => {
|
||||
asm_func.push_str(format!("\tmov rax, {}\n", n).as_str())
|
||||
},
|
||||
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;
|
||||
::std::ptr::write(ptr, 124010240120401240.12410240124120401240);
|
||||
},
|
||||
|
|
|
@ -51,6 +51,8 @@ pub enum Token {
|
|||
Fnaf, // fnaf
|
||||
#[token("let")]
|
||||
Let, // let
|
||||
#[token("global")]
|
||||
Global, // global
|
||||
#[token("if")]
|
||||
If, // if
|
||||
#[token("else")]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Expr<'a> {
|
||||
MathExpr(Math<'a>),
|
||||
FunCall(FunCall<'a>),
|
||||
|
@ -35,7 +35,7 @@ pub enum MathOperator {
|
|||
|
||||
// FUNCTIONS
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FunCall<'a> {
|
||||
pub name: &'a str,
|
||||
pub params: Vec<Rc<Expr<'a>>>,
|
||||
|
@ -81,8 +81,8 @@ pub struct ParamReference {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct IfCondition<'a> {
|
||||
pub left: Expr<'a>,
|
||||
pub right: Expr<'a>,
|
||||
pub left: Rc<Expr<'a>>,
|
||||
pub right: Rc<Expr<'a>>,
|
||||
pub cond: COND_OP,
|
||||
pub action: Vec<Expr<'a>>
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ pub fn parse_math(mut tokens: Lexer<Token>) -> Option<Expr> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn parse_var_declaration(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 {
|
||||
|
@ -44,12 +44,7 @@ pub fn parse_var_declaration(mut tokens: Lexer<Token>) -> Option<Expr> {
|
|||
if unwrap!(tokens) == Equal {
|
||||
let temp_token = unwrap!(tokens);
|
||||
if let Number(n) = temp_token {
|
||||
let value = Value::Number(n);
|
||||
println!("{:?}", value);
|
||||
tok = Some(Expr::VarDefinition(VarDefinition {name, value}));
|
||||
} else if temp_token == Identifier {
|
||||
let value = Value::Var(VarReference { name: tokens.slice() });
|
||||
tok = Some(Expr::VarDefinition(VarDefinition {name, value}));
|
||||
tok = Some(Expr::GlobalDefinition(Rc::new(VarDefinition {name, value: n})));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -62,9 +57,9 @@ pub fn parse_value<'a>(token: &(Option<Result<Token, ()>>, &'a str)) -> Option<E
|
|||
let mut value = None;
|
||||
|
||||
if let Number(n) = tt {
|
||||
value = Some(Value::Number(*n));
|
||||
value = Some(Expr::Number(*n));
|
||||
} else if *tt == Identifier {
|
||||
value = Some(Value::Var(VarReference { name: token.1 }));
|
||||
value = Some(Expr::Var(VarReference { name: token.1 }));
|
||||
}
|
||||
|
||||
value
|
||||
|
@ -85,7 +80,7 @@ pub fn parse_fun_call(mut tokens: Lexer<Token>) -> Option<Expr> {
|
|||
if unwrap!(tokens) == LeftParen {
|
||||
let mut params = Vec::new();
|
||||
while let Some(value) = parse_value!(tokens) {
|
||||
params.push(value);
|
||||
params.push(Rc::new(value));
|
||||
}
|
||||
tok = Some(Expr::FunCall(FunCall {name, params: params.clone()}));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue