Skip to content

Commit

Permalink
refactor(parser): new kind of ast node Item
Browse files Browse the repository at this point in the history
closes #84
  • Loading branch information
MilkeeyCat committed Oct 29, 2024
1 parent 3821fc3 commit b7be439
Show file tree
Hide file tree
Showing 13 changed files with 333 additions and 260 deletions.
29 changes: 14 additions & 15 deletions src/archs/amd64/amd64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
operands::{self, Base, EffectiveAddress, Immediate, Memory, Offset},
Argument, Destination, Source,
},
parser::{BitwiseOp, Block, CmpOp, Stmt},
parser::{BitwiseOp, Block, CmpOp, Item, Stmt},
register::{
allocator::{AllocatorError, RegisterAllocator},
Register,
Expand Down Expand Up @@ -671,10 +671,10 @@ impl Architecture for Amd64 {

for stmt in &block.0 {
match stmt {
Stmt::VarDecl(stmt2) => {
offset -= self.size(&stmt2.type_, scopes, scope_id) as isize;
Stmt::Item(Item::Variable(item)) => {
offset -= self.size(&item.type_, scopes, scope_id) as isize;

match scopes.get_symbol_mut(&stmt2.name, scope_id).unwrap() {
match scopes.get_symbol_mut(&item.name, scope_id).unwrap() {
Symbol::Local(local) => {
local.offset = Offset(offset);
}
Expand All @@ -694,23 +694,22 @@ impl Architecture for Amd64 {
offset = self.populate_offsets(&stmt.block, scopes, scope_id + 1, offset)?;
}
Stmt::For(stmt) => {
if let Some(Stmt::VarDecl(stmt2)) = stmt.initializer.as_deref() {
if let Some(Stmt::Item(Item::Variable(stmt2))) = stmt.initializer.as_deref() {
offset -= self.size(&stmt2.type_, scopes, scope_id) as isize;

//FIXME
unreachable!();
//match stmt.block.scope.symbol_table.find_mut(&stmt2.name).unwrap() {
// Symbol::Local(local) => {
// local.offset = Offset(offset);
// }
// _ => unreachable!(),
//};
match scopes.get_symbol_mut(&stmt2.name, scope_id).unwrap() {
Symbol::Local(local) => {
local.offset = Offset(offset);
}
_ => unreachable!(),
};
}

offset = self.populate_offsets(&stmt.block, scopes, scope_id + 1, offset)?;
}
Stmt::Return(_) | Stmt::Expr(_) | Stmt::Continue | Stmt::Break => (),
Stmt::Function(_) => unreachable!(),
Stmt::Return(_) | Stmt::Expr(_) | Stmt::Continue | Stmt::Break | Stmt::Item(_) => {
()
}
}
}

Expand Down
35 changes: 22 additions & 13 deletions src/codegen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::{
parser::{
BinOp, BitwiseOp, CmpOp, Expr, ExprArray, ExprArrayAccess, ExprBinary, ExprFunctionCall,
ExprIdent, ExprLit, ExprStruct, ExprStructAccess, ExprStructMethod, ExprUnary, Expression,
Stmt, StmtFor, StmtFunction, StmtIf, StmtReturn, StmtVarDecl, StmtWhile, UnOp,
Item, ItemFn, ItemVariable, Stmt, StmtFor, StmtIf, StmtReturn, StmtWhile, UnOp,
},
register::Register,
scope::Scopes,
Expand Down Expand Up @@ -45,7 +45,7 @@ impl CodeGen {
}
}

fn declare(&mut self, variable: StmtVarDecl) -> Result<(), CodeGenError> {
fn declare(&mut self, variable: ItemVariable) -> Result<(), CodeGenError> {
if self.scope_id == 0 {
self.arch.declare(
&variable.name,
Expand All @@ -68,7 +68,9 @@ impl CodeGen {
Ok(())
}

fn function(&mut self, func: StmtFunction) -> Result<(), CodeGenError> {
fn function(&mut self, func: ItemFn) -> Result<(), CodeGenError> {
self.scope_id += 1;

let offset = self
.arch
.populate_offsets(
Expand All @@ -80,11 +82,10 @@ impl CodeGen {
.unsigned_abs()
.next_multiple_of(self.arch.stack_alignment());

self.scope_id += 1;

self.arch.fn_preamble(
&func.name,
&func.signature.name,
&func
.signature
.params
.iter()
.map(|(_, type_)| type_.to_owned())
Expand All @@ -94,15 +95,15 @@ impl CodeGen {
self.scope_id,
)?;
self.scope_infos.push(ScopeInfo::Function {
label: func.name.clone(),
label: func.signature.name.clone(),
});

for stmt in func.block.0 {
self.stmt(stmt)?;
}

self.scope_infos.pop();
self.arch.fn_postamble(&func.name, offset);
self.arch.fn_postamble(&func.signature.name, offset);

Ok(())
}
Expand Down Expand Up @@ -724,9 +725,8 @@ impl CodeGen {

fn stmt(&mut self, stmt: Stmt) -> Result<(), CodeGenError> {
match stmt {
Stmt::Item(item) => self.item(item),
Stmt::Expr(expr) => self.expr(expr, None, None).map(|_| ()),
Stmt::VarDecl(var_decl) => self.declare(var_decl),
Stmt::Function(func) => self.function(func),
Stmt::Return(ret) => self.ret(ret),
Stmt::If(stmt) => self.if_stmt(stmt),
Stmt::While(stmt) => self.while_stmt(stmt),
Expand Down Expand Up @@ -1127,9 +1127,18 @@ impl CodeGen {
})
}

pub fn compile(&mut self, program: Vec<Stmt>) -> Result<Vec<u8>, CodeGenError> {
for stmt in program {
self.stmt(stmt)?;
pub fn item(&mut self, item: Item) -> Result<(), CodeGenError> {
Ok(match item {
Item::Variable(item) => self.declare(item)?,
Item::Fn(item) => self.function(item)?,
Item::Struct(_) => todo!(),
Item::ForeignFn(_) => (),
})
}

pub fn compile(&mut self, program: Vec<Item>) -> Result<Vec<u8>, CodeGenError> {
for item in program {
self.item(item)?;
}

Ok(self.arch.finish())
Expand Down
17 changes: 9 additions & 8 deletions src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
codegen::CodeGen,
lexer::Lexer,
parser,
passes::{MacroExpansion, SymbolResolver, TypeChecker},
passes::{SymbolResolver, TypeChecker},
};
use clap::Parser;
use std::{
Expand Down Expand Up @@ -46,16 +46,17 @@ pub fn compile(args: CompileArgs) -> Result<(), Box<dyn std::error::Error>> {
file.read_to_string(&mut source_code)?;

let lexer = Lexer::new(source_code);
let mut stmts = parser::Parser::new(lexer)?.parse()?;
let mut items = parser::Parser::new(lexer)?.parse()?;
//MacroExpansion::new(args.macro_libs).expand(&mut items);
let scopes = SymbolResolver::new().run_pass(&mut items)?;

MacroExpansion::new(args.macro_libs).expand(&mut stmts);
let scopes = SymbolResolver::new().run_pass(&mut stmts)?;
TypeChecker::new(&scopes).run_pass(&stmts)?;

dbg!(&stmts);
dbg!(&scopes);

let code = CodeGen::new(Box::new(Amd64::new()), scopes).compile(stmts)?;
TypeChecker::new(&scopes).run_pass(&items)?;

dbg!(&items);

let code = CodeGen::new(Box::new(Amd64::new()), scopes).compile(items)?;

if args.assembly_only {
let asm_filename = args.file.with_extension("s");
Expand Down
53 changes: 53 additions & 0 deletions src/parser/item.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use super::{Block, Expr};
use crate::types::Type;

#[derive(Debug, Clone, PartialEq)]
pub enum Item {
Variable(ItemVariable),
Struct(ItemStruct),
Fn(ItemFn),
ForeignFn(ItemForeignFn),
}

#[derive(Debug, Clone, PartialEq)]
pub struct ItemVariable {
pub type_: Type,
pub name: String,
pub value: Option<Expr>,
}

#[derive(Debug, Clone, PartialEq)]
pub struct ItemStruct {
pub name: String,
pub fields: Vec<(String, Type)>,
pub methods: Vec<Method>,
}

#[derive(Debug, Clone, PartialEq)]
pub enum MethodKind {
Static,
Instance,
}

#[derive(Debug, Clone, PartialEq)]
pub struct Method {
pub kind: MethodKind,
pub signature: Signature,
pub block: Block,
}

#[derive(Debug, Clone, PartialEq)]
pub struct Signature {
pub name: String,
pub params: Vec<(String, Type)>,
pub return_type: Type,
}

#[derive(Debug, Clone, PartialEq)]
pub struct ItemFn {
pub signature: Signature,
pub block: Block,
}

#[derive(Debug, Clone, PartialEq)]
pub struct ItemForeignFn(pub Signature);
10 changes: 8 additions & 2 deletions src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
mod error;
pub mod expr;
mod item;
mod op;
mod parser;
mod precedence;
mod stmt;

pub mod expr;

pub use error::ParserError;
pub use expr::*;
pub use item::{Item, ItemFn, ItemForeignFn, ItemStruct, ItemVariable, Signature};
pub use op::{BinOp, BitwiseOp, CmpOp, OpParseError, UnOp};
pub use parser::Parser;
pub use precedence::Precedence;
pub use stmt::{Block, Stmt, StmtFor, StmtFunction, StmtIf, StmtReturn, StmtVarDecl, StmtWhile};
pub use stmt::{Stmt, StmtFor, StmtIf, StmtReturn, StmtWhile};

#[derive(Debug, Clone, PartialEq)]
pub struct Block(pub Vec<Stmt>);
Loading

0 comments on commit b7be439

Please sign in to comment.