Made the backend work for math, working on the frontend
This commit is contained in:
parent
c83b131381
commit
626f1694f4
159
TAGS~
159
TAGS~
|
@ -1,159 +0,0 @@
|
||||||
|
|
||||||
Cargo.lock,0
|
|
||||||
|
|
||||||
Cargo.toml,0
|
|
||||||
|
|
||||||
README.md,130
|
|
||||||
# ![SkyLang](.images/slang_logo_dark_transparent_not_motto.png)![SkyLang](.images/slang_logo_dark_transparent_not_motto.png)1,0
|
|
||||||
|
|
||||||
src/codegen/fasm.rs,91
|
|
||||||
pub fn fasm_codegen(exprs: &Vec<Expr>, not_a_function: bool) -> String {fasm_codegen3,27
|
|
||||||
|
|
||||||
src/codegen/fasmarm.rs,0
|
|
||||||
|
|
||||||
src/codegen/mod.rs,23
|
|
||||||
pub mod fasm;fasm1,0
|
|
||||||
|
|
||||||
src/lex/mod.rs,47
|
|
||||||
pub mod tok;tok1,0
|
|
||||||
pub mod parse;parse2,13
|
|
||||||
|
|
||||||
src/lex/parse.rs,755
|
|
||||||
pub fn match_single_char<'a>(word: &'a str) -> Option<Token<'a>> {match_single_char6,40
|
|
||||||
macro_rules! tok {tok7,107
|
|
||||||
pub fn match_keyword<'a>(word: &'a str) -> Option<Token<'a>> {match_keyword38,697
|
|
||||||
macro_rules! tok {tok39,760
|
|
||||||
pub fn match_two_char<'a>(word: &'a str) -> Option<Token<'a>> {match_two_char66,1310
|
|
||||||
macro_rules! tok {tok67,1374
|
|
||||||
pub fn match_string_literal<'a>(word: &'a str) -> Option<Token<'a>> {match_string_literal85,1681
|
|
||||||
macro_rules! tok {tok86,1751
|
|
||||||
pub fn match_int_literal<'a>(word: &'a str) -> Option<Token<'a>> {match_int_literal114,2191
|
|
||||||
macro_rules! tok {tok115,2258
|
|
||||||
pub fn match_identifier<'a>(word: &'a str) -> Option<Token<'a>> {match_identifier134,2562
|
|
||||||
macro_rules! tok {tok135,2628
|
|
||||||
|
|
||||||
src/lex/tok.rs,2268
|
|
||||||
pub struct Token<'a> {Token6,79
|
|
||||||
tt: TokenType,tt7,102
|
|
||||||
word: &'a str,word8,121
|
|
||||||
pub enum TokenType {TokenType12,160
|
|
||||||
EOF,EOF13,181
|
|
||||||
Semicolon, // ;Semicolon16,222
|
|
||||||
Equal, // =Equal17,242
|
|
||||||
LeftParen, // (LeftParen18,258
|
|
||||||
RightParen, // )RightParen19,278
|
|
||||||
LeftBrace, // {LeftBrace20,299
|
|
||||||
RightBrace, // }RightBrace21,319
|
|
||||||
Comma, // ,Comma22,340
|
|
||||||
Dot, // .Dot23,356
|
|
||||||
Minus, // -Minus24,370
|
|
||||||
Plus, // +Plus25,386
|
|
||||||
Slash, // /Slash26,401
|
|
||||||
Star, // *Star27,417
|
|
||||||
Percent, // %Percent28,432
|
|
||||||
Bang, // !Bang29,450
|
|
||||||
Colon, // :Colon30,465
|
|
||||||
Less, // <Less31,481
|
|
||||||
Greater, // >Greater32,496
|
|
||||||
Fn, // fnFn35,531
|
|
||||||
Let, // letLet36,546
|
|
||||||
If, // ifIf37,562
|
|
||||||
Else, // elseElse38,577
|
|
||||||
While, // whileWhile39,595
|
|
||||||
Elif, // elifElif40,615
|
|
||||||
Return, // returnReturn41,633
|
|
||||||
For, // forFor42,655
|
|
||||||
In, // inIn43,671
|
|
||||||
Break, // breakBreak44,686
|
|
||||||
Continue, // continueContinue45,706
|
|
||||||
EqualEqual, // ==EqualEqual48,761
|
|
||||||
BangEqual, // !=BangEqual49,784
|
|
||||||
LessEqual, // <=LessEqual50,806
|
|
||||||
GreaterEqual, // >=GreaterEqual51,828
|
|
||||||
String, // A string literal.String54,873
|
|
||||||
Number, // An integer.Number55,906
|
|
||||||
Identifier, // An identifier.Identifier56,933
|
|
||||||
True, // trueTrue57,967
|
|
||||||
False, // falseFalse58,985
|
|
||||||
Null, // NoneNull59,1005
|
|
||||||
Error, // A syntax error.Error62,1037
|
|
||||||
pub struct Lexer<'a> {Lexer66,1087
|
|
||||||
source: &'a str,source67,1110
|
|
||||||
tokens: Vec<Token<'a>>,tokens68,1131
|
|
||||||
current: usize,current69,1159
|
|
||||||
after: &'a strafter70,1179
|
|
||||||
impl<'a> Lexer<'a> {Lexer73,1201
|
|
||||||
pub fn new() -> Self {new74,1222
|
|
||||||
impl<'a> std::iter::Iterator for Lexer<'a> {Lexer84,1386
|
|
||||||
type Item = Option<char>;Item85,1431
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {next87,1462
|
|
||||||
impl<'a> From<&'a str> for Lexer<'a> {Lexer92,1579
|
|
||||||
fn from(value: &'a str) -> Self {from93,1618
|
|
||||||
impl<'a> From<&'a std::string::String> for Lexer<'a> {Lexer103,1800
|
|
||||||
fn from(value: &'a std::string::String) -> Self {from104,1855
|
|
||||||
impl<'a> Token<'a> {Token114,2057
|
|
||||||
pub fn new(tt: TokenType, word: &'a str) -> Self {new115,2078
|
|
||||||
pub fn empty() -> Self {empty122,2171
|
|
||||||
|
|
||||||
src/main.rs,102
|
|
||||||
pub mod lex;lex3,21
|
|
||||||
pub mod codegen;codegen4,34
|
|
||||||
pub mod parse;parse7,106
|
|
||||||
fn main() {main9,122
|
|
||||||
|
|
||||||
src/parse/ast.rs,2125
|
|
||||||
pub enum Expr<'a> {Expr2,17
|
|
||||||
MathExpr(Math<'a>),MathExpr3,37
|
|
||||||
FunCall(FunCall<'a>),FunCall4,61
|
|
||||||
FunDefinition(FunDefinition<'a>),FunDefinition5,87
|
|
||||||
VarDefinition(VarDefinition<'a>),VarDefinition6,125
|
|
||||||
Return(Value<'a>),Return7,163
|
|
||||||
If(IfStatement<'a>),If8,186
|
|
||||||
BreakpointBreakpoint9,211
|
|
||||||
pub struct Math<'a> {Math15,279
|
|
||||||
pub left: &'a Value<'a>,left16,301
|
|
||||||
pub right: &'a Value<'a>,right17,330
|
|
||||||
pub operator: MathOperatoroperator18,360
|
|
||||||
pub enum MathOperator {MathOperator22,424
|
|
||||||
OP_ADD, // AdditionOP_ADD23,448
|
|
||||||
OP_SUB, // SubtractionOP_SUB24,472
|
|
||||||
OP_DIV, // DivisionOP_DIV25,499
|
|
||||||
OP_MULT, // MultiplicationOP_MULT26,523
|
|
||||||
OP_MOD, // ModuloOP_MOD27,554
|
|
||||||
pub struct FunCall<'a> {FunCall33,610
|
|
||||||
pub name: &'a str,name34,635
|
|
||||||
pub params: Vec<Value<'a>>,params35,658
|
|
||||||
pub struct FunDefinition<'a> {FunDefinition39,710
|
|
||||||
pub name: &'a str,name40,741
|
|
||||||
pub contents: Vec<Expr<'a>>,contents41,764
|
|
||||||
pub struct FunParamDef<'a> {FunParamDef45,817
|
|
||||||
name: &'a str,name46,846
|
|
||||||
number: u64,number47,865
|
|
||||||
pub struct FunParamCall<'a> {FunParamCall51,902
|
|
||||||
pub value: Value<'a>,value52,932
|
|
||||||
pub struct VarDefinition<'a> {VarDefinition58,992
|
|
||||||
pub name: &'a str,name59,1023
|
|
||||||
pub value: Value<'a>,value60,1046
|
|
||||||
pub struct VarReference<'a> {VarReference65,1106
|
|
||||||
pub name: &'a str,name66,1136
|
|
||||||
pub struct ParamReference {ParamReference70,1192
|
|
||||||
pub param_number: u64,param_number71,1220
|
|
||||||
pub enum Value<'a> {Value75,1280
|
|
||||||
Var(VarReference<'a>),Var76,1301
|
|
||||||
Param(ParamReference),Param77,1328
|
|
||||||
Number(u64),Number78,1355
|
|
||||||
pub struct IfStatement<'a> {IfStatement82,1392
|
|
||||||
pub condition: Condition<'a>,condition83,1421
|
|
||||||
pub if_true: Vec<Expr<'a>>,if_true84,1455
|
|
||||||
pub struct Condition<'a> {Condition88,1507
|
|
||||||
pub left: Value<'a>,left89,1534
|
|
||||||
pub right: Value<'a>,right90,1559
|
|
||||||
pub between: COND_OP,between91,1585
|
|
||||||
pub enum COND_OP {COND_OP95,1631
|
|
||||||
EQ,EQ96,1650
|
|
||||||
NE,NE97,1658
|
|
||||||
impl<'a> Value<'a> {Value100,1669
|
|
||||||
pub fn unwrap(&self) -> String {unwrap101,1690
|
|
||||||
|
|
||||||
src/parse/mod.rs,21
|
|
||||||
pub mod ast;ast1,0
|
|
|
@ -2,35 +2,14 @@ use crate::parse::ast::*;
|
||||||
use skylang::temp;
|
use skylang::temp;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
const REGISTERS: [&str; 9] = ["r10", "r11", "r12", "r13", "r14", "rsp", "rbp", "rdp", "rdi"];
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct FasmCodegen {
|
pub struct FasmCodegen;
|
||||||
register_counter: usize,
|
|
||||||
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 {
|
impl FasmCodegen {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
FasmCodegen {
|
FasmCodegen
|
||||||
register_counter: 0,
|
|
||||||
operation_queue: Vec::new(),
|
|
||||||
use_queue: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fasm_codegen(&mut self, exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
pub fn fasm_codegen(&mut self, exprs: &Vec<Expr>, not_a_function: bool) -> String {
|
||||||
macro_rules! fasm_codegen {
|
macro_rules! fasm_codegen {
|
||||||
// Macro to make calling fasm_codegen function easier.
|
// Macro to make calling fasm_codegen function easier.
|
||||||
|
@ -71,46 +50,27 @@ impl FasmCodegen {
|
||||||
match expr {
|
match expr {
|
||||||
// If the expression is a math expression.
|
// If the expression is a math expression.
|
||||||
Expr::MathExpr(e) => {
|
Expr::MathExpr(e) => {
|
||||||
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 = &self.register_counter;
|
|
||||||
if self.use_queue {
|
|
||||||
println!("self.use_queue");
|
|
||||||
if let Some(OperationQueue::RegisterCounter(q)) = self.operation_queue.pop() {
|
|
||||||
register_counter = &q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dbg!(*register_counter, self.register_counter, self.use_queue);
|
|
||||||
unwrap!(e.left);
|
|
||||||
self.register_counter += 1;
|
|
||||||
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);
|
unwrap!(e.right);
|
||||||
self.register_counter += 1;
|
asm_start.push_str("\tpush rax\n");
|
||||||
dbg!(*register_counter, self.register_counter, self.use_queue);
|
unwrap!(e.left);
|
||||||
asm_start.push_str(format!("\tmov {}, rax\n", REGISTERS[*register_counter]).as_str());
|
asm_start.push_str("\tpush rax\n");
|
||||||
self.register_counter += 1;
|
|
||||||
match e.operator {
|
match e.operator {
|
||||||
// If the operator is addition.
|
// If the operator is addition.
|
||||||
MathOperator::OP_ADD => {
|
MathOperator::OP_ADD => {
|
||||||
asm_start.push_str(format!("\tadd {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str());
|
asm_start.push_str("\tpop r10\n");
|
||||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str());
|
asm_start.push_str("\tpop r11\n");
|
||||||
|
asm_start.push_str("\tadd r10, r11\n");
|
||||||
|
asm_start.push_str("\tmov rax, r10\n");
|
||||||
|
|
||||||
// r10 ← r10 + r11; rax ← r10;
|
// r10 ← r10 + r11; rax ← r10;
|
||||||
// The sum will now be stored in the %rax register.
|
// The sum will now be stored in the %rax register.
|
||||||
},
|
},
|
||||||
// If the operator is multiplication.
|
// If the operator is multiplication.
|
||||||
MathOperator::OP_MULT => {
|
MathOperator::OP_MULT => {
|
||||||
asm_start.push_str(format!("\timul {}, {}\n", REGISTERS[*register_counter - 1], REGISTERS[*register_counter]).as_str());
|
asm_start.push_str("\tpop r10\n");
|
||||||
asm_start.push_str(format!("\tmov rax, {}\n", REGISTERS[*register_counter - 1]).as_str());
|
asm_start.push_str("\tpop r11\n");
|
||||||
|
asm_start.push_str("\timul r10, r11\n");
|
||||||
|
asm_start.push_str("\tmov rax, r10\n");
|
||||||
|
|
||||||
// r10 ← r10 * r11; rax ← r10;
|
// r10 ← r10 * r11; rax ← r10;
|
||||||
// The product will now be stored in the %rax register.
|
// The product will now be stored in the %rax register.
|
||||||
|
|
|
@ -5,7 +5,7 @@ use core::iter::Peekable;
|
||||||
|
|
||||||
pub use Token::*;
|
pub use Token::*;
|
||||||
|
|
||||||
#[derive(Debug, Logos, PartialEq, Eq)]
|
#[derive(Debug, Logos, PartialEq, Eq, Clone)]
|
||||||
#[logos(skip r"[ \t\n\f]+")]
|
#[logos(skip r"[ \t\n\f]+")]
|
||||||
pub enum Token {
|
pub enum Token {
|
||||||
// SINGLE CHARACTER TOKENS
|
// SINGLE CHARACTER TOKENS
|
||||||
|
|
|
@ -52,7 +52,7 @@ fn main() {
|
||||||
// println!("{}", fc);
|
// println!("{}", fc);
|
||||||
let parsed = "3*10+5";
|
let parsed = "3*10+5";
|
||||||
|
|
||||||
let lexer = Token::lexer(parsed);
|
let mut lexer = Token::lexer(parsed);
|
||||||
|
|
||||||
println!("\"{}\"", parsed);
|
println!("\"{}\"", parsed);
|
||||||
arrow!(" ");
|
arrow!(" ");
|
||||||
|
|
|
@ -11,17 +11,16 @@ macro_rules! unwrap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_math(mut tokens: Lexer<Token>) -> Option<Expr> {
|
pub fn parse_math(mut tokens: Lexer<Token>) -> Option<Expr> {
|
||||||
// Is it a Value? → Is it an operator? → Is it a value?
|
if let Some(left) = parse_math(tokens) {
|
||||||
|
if let Some(op) = match_operator(tokens) {
|
||||||
if let Some(Ok(Number(left))) = tokens.next() {
|
if let Some(Ok(Number(right))) = tokens.next() {
|
||||||
if let Some(op) = match_operator(&mut tokens) {
|
return Some(Expr::MathExpr(Math {left: Rc::new(left), right: Rc::new(Expr::Number(right)), operator: op}));
|
||||||
if let Some(right) = parse_math(tokens) {
|
|
||||||
return Some(Expr::MathExpr(Math {left: Rc::new(Expr::Number(left)), right: Rc::new(right), operator: op}));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return Some(Expr::Number(left));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ pub fn parse_global_declaration(mut tokens: Lexer<Token>) -> Option<Expr> {
|
||||||
tok
|
tok
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn match_operator(tokens: &mut Lexer<Token>) -> Option<MathOperator> {
|
pub fn match_operator(mut tokens: Lexer<Token>) -> Option<MathOperator> {
|
||||||
if let Some(Ok(token)) = tokens.next() {
|
if let Some(Ok(token)) = tokens.next() {
|
||||||
return match token {
|
return match token {
|
||||||
Plus => Some(MathOperator::OP_ADD),
|
Plus => Some(MathOperator::OP_ADD),
|
||||||
|
|
Loading…
Reference in a new issue