not finisshed
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)?;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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_")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user