not finisshed

This commit is contained in:
MCorange
2024-03-14 12:40:26 +02:00
parent c2f6f97590
commit 6ae49ea4c8
9 changed files with 456 additions and 328 deletions

View File

@@ -6,7 +6,6 @@ use anyhow::bail;
use crate::{cli::{CliArgs, CompilationTarget}, types::ast::Program};
use std::{collections::HashMap, fs::File, io::{BufWriter, Write}, path::{Path, PathBuf}, process::Command};
use self::utils::run_cmd;
pub trait Compiler {

View File

@@ -14,6 +14,7 @@ use super::Compiler;
pub struct X86_64LinuxNasmCompiler {
strings: Vec<String>,
func_mem_i: Vec<usize>,
if_i: usize,
while_i: usize,
used_consts: Vec<String>
@@ -354,8 +355,14 @@ impl X86_64LinuxNasmCompiler {
writeln!(fd, "; WHILE({id}) END")?;
},
AstNode::Module(m) => self.handle_module(fd, prog, m)?,
AstNode::Memory(_) => todo!(),
AstNode::MemUse(_) => todo!(),
AstNode::Memory(m) => {
if !m.statc {
todo!()
}
},
AstNode::MemUse(_) => {
},
AstNode::ConstUse(c) => {
self.used_consts.push(c.ident.clone());
writeln!(fd, " mov rax, qword [c_{}]", c.ident)?;

View File

@@ -157,9 +157,11 @@ impl Lexer {
}
'/' if chars.get(idx + 1) == Some(&'/') => {
while chars.get(idx) != Some(&'\n') {
let mut c = chars.get(idx);
while c.is_some() && c != Some(&'\n') {
self.loc.inc_col();
idx += 1;
c = chars.get(idx);
}
self.loc.inc_line();
}

View File

@@ -6,9 +6,9 @@ use std::{collections::HashMap, path::Path};
use anyhow::{bail, Result};
use crate::{cli::CliArgs, lexer::Lexer, types::{ast::{AstNode, Block, ConstUse, Constant, FnCall, Function, If, MemUse, Module, Program, While}, common::Loc, token::{InstructionType, KeywordType, Token, TokenType}}};
use crate::{cli::CliArgs, lexer::Lexer, types::{ast::{AstNode, Block, ConstUse, Constant, FnCall, Function, If, MemUse, Memory, Module, Program, While}, common::Loc, token::{InstructionType, KeywordType, Token, TokenType}}};
use self::{builtin::get_builtin_symbols, precompiler::precompile, utils::{expect, peek_check, peek_check_multiple, PeekResult}};
use self::{builtin::get_builtin_symbols, precompiler::{precompile_const, precompile_mem}, utils::{expect, peek_check, peek_check_multiple, PeekResult}};
bitflags::bitflags! {
@@ -69,8 +69,8 @@ fn parse_next(cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec<Token>, f
match kw {
KeywordType::If => parse_if(&token, cli_args, prog, tokens)?,
KeywordType::While => parse_while(&token, cli_args, prog, tokens)?,
KeywordType::Include => parse_include(&token, cli_args, prog, tokens)?, //TODO: implement include
KeywordType::Memory => todo!(),
KeywordType::Include => parse_include(&token, cli_args, prog, tokens)?,
KeywordType::Memory => parse_memory(&token, cli_args, prog, tokens, is_module_root)?,
KeywordType::Constant => parse_const(&token, cli_args, prog, tokens)?,
KeywordType::Function => parse_function(&token, cli_args, prog, tokens, flags)?,
KeywordType::Struct => todo!(),
@@ -105,6 +105,43 @@ fn parse_next(cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec<Token>, f
Ok(ret)
}
fn parse_memory(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec<Token>, is_module_root: bool) -> Result<AstNode> {
let name = expect(tokens, TokenType::Unknown(String::new()))?;
let mut body = Vec::new();
loop {
let t = peek_check(tokens, TokenType::Keyword(KeywordType::End));
match t {
PeekResult::Correct(_) => break,
PeekResult::Wrong(_) => (),
PeekResult::None => panic!("idk what to do herre"),
}
body.push(parse_next(cli_args, prog, tokens, Flags::empty(), false)?);
}
expect(tokens, TokenType::Keyword(KeywordType::End))?;
let val = precompile_mem(prog, body)?;
let name = name.lexem.clone()
.replace("(", "_OPRN_")
.replace(")", "_CPRN_");
let def = Memory{
loc: org.loc(),
ident: name.clone(),
size: val,
statc: is_module_root,
};
prog.memories.insert(name, def.clone());
Ok(AstNode::Memory(def))
}
// TODO: Extern functions
fn parse_function(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut Vec<Token>, flags: Flags ) -> Result<AstNode> {
@@ -509,20 +546,17 @@ fn parse_const(org: &Token, cli_args: &CliArgs, prog: &mut Program, tokens: &mut
}
expect(tokens, TokenType::Keyword(KeywordType::End))?;
let val = precompile(prog, body, &mut Vec::new())?;
let val = precompile_const(prog, body, &mut Vec::new())?;
let name = name.lexem.clone()
.replace("(", "_OPRN_")
.replace(")", "_CPRN_");
let def = Constant{
loc: org.loc(),
ident: name.clone(),
ident: name.lexem.clone(),
value: Box::new(val),
};
prog.constants.insert(name, def.clone());
prog.constants.insert(name.lexem, def.clone());
Ok(AstNode::Constant(def))
}

View File

@@ -3,7 +3,23 @@ use anyhow::bail;
use crate::types::{ast::{AstNode, Program}, common::Loc, token::{InstructionType, TokenType}};
pub fn precompile(prog: &Program, ast: Vec<AstNode>, stack: &mut Vec<usize> ) -> anyhow::Result<AstNode> {
pub fn precompile_mem(prog: &Program, ast: Vec<AstNode> ) -> anyhow::Result<usize> {
match precompile_const(prog, ast, &mut Vec::new()) {
Ok(v) => {
match v {
AstNode::Int(_, i) => {
return Ok(i)
}
_ => {
error!("memories can only have numbers or types in their size");
bail!("")
}
}
},
Err(e) => bail!(e),
}
}
pub fn precompile_const(prog: &Program, ast: Vec<AstNode>, stack: &mut Vec<usize> ) -> anyhow::Result<AstNode> {
for node in ast.clone() {
match &node {
AstNode::ConstUse(c) => {

View File

@@ -135,6 +135,7 @@ pub struct Constant {
pub struct Memory {
pub loc: Loc,
pub ident: String,
pub statc: bool,
pub size: usize // bytes
}
@@ -145,4 +146,28 @@ pub struct Program {
pub functions: HashMap<String, Function>,
pub constants: HashMap<String, Constant>,
pub memories: HashMap<String, Memory>,
}
impl EscIdent for Constant {
fn ident(&self) -> String {
self.ident.clone()
}
}
impl EscIdent for Memory {
fn ident(&self) -> String {
self.ident.clone()
}
}
impl EscIdent for Function {
fn ident(&self) -> String {
self.ident.clone()
}
}
pub trait EscIdent {
fn ident(&self) -> String;
fn get_ident_escaped(&self) -> String {
self.ident().replace("(", "_OPRN_")
.replace(")", "_CPRN_")
}
}