the light is getting closer

This commit is contained in:
2025-05-04 04:12:56 -04:00
parent 5f36be9de9
commit 6583d47ef8
23 changed files with 1261 additions and 740 deletions
+4 -3
View File
@@ -1,14 +1,15 @@
use crate::{
compiler::arch::riscv::Reg,
ir::{
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, Type, UInstruction, VarInst
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, Type, UInstruction, VarInst,
VarInstID,
},
parser::PAsmBlockArg,
};
use super::{FnLowerCtx, FnLowerable, PAsmBlock, PInstruction, PUAsmBlockArg};
type PLAsmBlockArg = PAsmBlockArg<Reg, VarInst>;
type PLAsmBlockArg = PAsmBlockArg<Reg, VarInstID>;
impl FnLowerable for PInstruction {
type Output = RV64Instruction;
@@ -19,7 +20,7 @@ impl FnLowerable for PInstruction {
}
impl FnLowerable for PAsmBlock {
type Output = VarInst;
type Output = VarInstID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
let mut args = Vec::new();
+3 -3
View File
@@ -1,13 +1,13 @@
use crate::{
ir::{Type, UInstruction, UVar, VarInst},
ir::{Type, UInstruction, UVar, VarInst, VarInstID},
parser::{PConstStatement, PStatementLike},
};
use super::{FnLowerCtx, FnLowerable, Import, PBlock, PStatement};
impl FnLowerable for PBlock {
type Output = VarInst;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
type Output = VarInstID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInstID> {
let mut last = None;
let mut statements = Vec::new();
let mut fn_nodes = Vec::new();
+36 -31
View File
@@ -1,12 +1,12 @@
use super::{func::FnLowerCtx, FnLowerable, PExpr, PostfixOp};
use crate::{
ir::{Type, UData, UInstruction, VarInst},
ir::{Type, UData, UInstruction, VarInst, VarInstID},
parser::InfixOp,
};
impl FnLowerable for PExpr {
type Output = VarInst;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
type Output = VarInstID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInstID> {
let mut e = self;
let mut path = Vec::new();
while let PExpr::Member(node, ident) = e {
@@ -20,40 +20,40 @@ impl FnLowerable for PExpr {
Some(match e {
PExpr::Lit(l) => match l {
super::PLiteral::String(s) => {
let dest = ctx.b.temp_var(ctx.origin, Type::Bits(8).slice(ctx.b.p));
let dst = ctx.temp_var(ctx.origin, Type::Bits(8).slice(ctx.p));
let data = s.as_bytes().to_vec();
let src = ctx.b.def_data(UData {
let src = ctx.def_data(UData {
name: format!("string \"{}\"", s.replace("\n", "\\n")),
ty: Type::Bits(8).arr(ctx.b.p, data.len() as u32),
ty: ctx.def_ty(Type::Bits(8).arr(ctx.b.p, data.len() as u32)),
content: data,
});
ctx.push(UInstruction::LoadSlice { dst: dest, src });
dest
ctx.push(UInstruction::LoadSlice { dst, src });
dst
}
super::PLiteral::Char(c) => {
let ty = Type::Bits(8);
let dest = ctx.b.temp_var(ctx.origin, ty.clone());
let src = ctx.b.def_data(UData {
let ty = ctx.def_ty(Type::Bits(8));
let dst = ctx.temp_var(ctx.origin, ty.clone());
let src = ctx.def_data(UData {
name: format!("char '{c}'"),
ty,
content: c.to_string().as_bytes().to_vec(),
});
ctx.push(UInstruction::LoadData { dst: dest, src });
dest
ctx.push(UInstruction::LoadData { dst, src });
dst
}
super::PLiteral::Number(n) => {
// TODO: temp
let ty = Type::Bits(64);
let dest = ctx.b.temp_var(ctx.origin, ty.clone());
let src = ctx.b.def_data(UData {
let ty = ctx.def_ty(Type::Bits(64));
let dst = ctx.temp_var(ctx.origin, ty.clone());
let src = ctx.def_data(UData {
name: format!("num {n:?}"),
ty,
content: n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(),
});
ctx.push(UInstruction::LoadData { dst: dest, src });
dest
ctx.push(UInstruction::LoadData { dst, src });
dst
}
super::PLiteral::Unit => ctx.b.temp_var(ctx.origin, Type::Unit),
super::PLiteral::Unit => ctx.temp_var(ctx.origin, Type::Unit),
},
PExpr::Ident(i) => ctx.var(i),
PExpr::BinaryOp(op, e1, e2) => match op {
@@ -79,14 +79,17 @@ impl FnLowerable for PExpr {
PostfixOp::Ref => {
let ty = Type::Ref(ctx.b.infer());
let dest = ctx.temp(ty);
ctx.push(UInstruction::Ref { dst: dest, src: res });
ctx.push(UInstruction::Ref {
dst: dest,
src: res,
});
dest
}
PostfixOp::Deref => {
let ty = Type::Deref(ctx.b.infer());
let dest = ctx.temp(ty);
ctx.push(UInstruction::Deref { dst: dest, src: res });
dest
let dst = ctx.temp(ty);
ctx.push(UInstruction::Deref { dst, src: res });
dst
}
PostfixOp::Not => todo!(),
}
@@ -102,7 +105,7 @@ impl FnLowerable for PExpr {
}
let dest = ctx.temp(Type::Infer);
ctx.push(UInstruction::Call {
dst: VarInst { status: , origin: () },
dst: dest,
f: fe,
args: nargs,
});
@@ -110,26 +113,28 @@ impl FnLowerable for PExpr {
}
PExpr::Group(e) => e.lower(ctx)?,
PExpr::Construct(e, map) => {
let dest = ctx.temp(Type::Placeholder);
ctx.push(UInstruction::Construct { dst: dest, fields: () });
dest
let dst = ctx.temp(Type::Infer);
let struc = e.lower(ctx)?;
let fields = map.lower(ctx)?;
ctx.push(UInstruction::Construct { dst, struc, fields });
dst
}
PExpr::If(cond, body) => {
let cond = cond.lower(ctx)?;
ctx.b.push();
ctx.var_stack.push();
let mut body_ctx = ctx.branch();
body.lower(&mut body_ctx);
let body = body_ctx.instructions;
ctx.b.pop();
ctx.var_stack.pop();
ctx.push(UInstruction::If { cond, body });
return None;
}
PExpr::Loop(body) => {
ctx.b.push();
ctx.var_stack.push();
let mut body_ctx = ctx.branch();
body.lower(&mut body_ctx);
let body = body_ctx.instructions;
ctx.b.pop();
ctx.var_stack.pop();
ctx.push(UInstruction::Loop { body });
return None;
}
+61 -27
View File
@@ -1,12 +1,16 @@
use std::collections::HashMap;
use std::{
collections::HashMap,
ops::{Deref, DerefMut},
};
use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Imports, Node, PFunction};
use crate::{
ir::{
FnID, Origin, Typable, Type, UFunc, UInstrInst, UInstruction, UModuleBuilder, UVar, VarID,
VarInst, VarStatus,
FnID, GenericID, ModPath, Origin, Typable, Type, UFunc, UInstrInst, UInstruction,
UModuleBuilder, VarID, VarInst, VarInstID, VarStatus,
},
parser, util::NameStack,
parser,
util::NameStack,
};
impl Node<PFunction> {
@@ -32,13 +36,9 @@ impl PFunction {
) -> Option<FnID> {
let header = self.header.as_ref()?;
let name = header.name.as_ref()?.0.clone();
let (generic_args, args, ret) = if let Some(header) = self.header.as_ref() {
let (generics, args, ret) = if let Some(header) = self.header.as_ref() {
(
header
.gargs
.iter()
.map(|a| Some(a.lower(b, output)))
.collect(),
header.gargs.iter().flat_map(|a| a.lower(b)).collect(),
header
.args
.iter()
@@ -50,27 +50,32 @@ impl PFunction {
},
)
} else {
(Vec::new(), Vec::new(), b.error)
(Vec::new(), Vec::new(), b.tc.error)
};
let gargs = generics.iter().map(|g| g.1).collect();
let generics = generics.into_iter().collect();
let instructions = {
let mut var_stack = Vec::new();
let mut var_stack = NameStack::new();
let mut ctx = FnLowerCtx {
instructions: Vec::new(),
var_stack: &mut var_stack,
b,
output,
origin: self.body.origin,
generics: &generics,
imports,
};
if let Some(src) = self.body.lower(&mut ctx) {
ctx.instructions.push(UInstrInst {
origin: src.origin,
let res = self.body.lower(&mut ctx);
let mut instructions = ctx.instructions;
if let Some(src) = res {
let origin = b.vars_insts[src].origin;
instructions.push(UInstrInst {
origin,
i: UInstruction::Ret { src },
});
}
ctx.instructions
instructions
};
let gargs = args.iter().map(|a| b.vars[a].ty).collect();
let f = UFunc {
origin,
gargs,
@@ -90,18 +95,32 @@ pub struct FnLowerCtx<'a, 'b> {
pub origin: FileSpan,
pub imports: &'a mut Imports,
pub var_stack: &'a mut NameStack<VarID>,
pub generics: &'a HashMap<String, GenericID>,
}
impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn var(&mut self, node: &Node<parser::PIdent>) -> VarInst {
if let Some(n) = node.as_ref() {
if let Some(&var) = self.var_stack.search(&n.0) {
return VarInst {
status: VarStatus::Res(var),
origin: node.origin,
pub fn var(&mut self, node: &Node<parser::PIdent>) -> VarInstID {
let inst = VarInst {
status: if let Some(n) = node.as_ref() {
if let Some(&var) = self.var_stack.search(&n.0) {
VarStatus::Var(var)
} else {
VarStatus::Unres {
path: ModPath {
id: self.b.module,
path: Vec::new(),
},
name: n.0.clone(),
gargs: Vec::new(),
fields: Vec::new(),
}
}
}
}
} else {
VarStatus::Cooked
},
origin: node.origin,
};
self.def_var_inst(inst)
}
pub fn err(&mut self, msg: String) {
self.output.err(CompilerMsg::new(msg, self.origin))
@@ -109,7 +128,7 @@ impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn err_at(&mut self, span: FileSpan, msg: String) {
self.output.err(CompilerMsg::new(msg, span))
}
pub fn temp<T: Typable>(&mut self, ty: Type) -> VarInst {
pub fn temp<T: Typable>(&mut self, ty: T) -> VarInstID {
self.b.temp_var(self.origin, ty)
}
pub fn push(&mut self, i: UInstruction) {
@@ -118,10 +137,11 @@ impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn push_at(&mut self, i: UInstruction, span: FileSpan) {
self.instructions.push(UInstrInst { i, origin: span });
}
pub fn branch(&'a mut self) -> FnLowerCtx<'a, 'b> {
pub fn branch<'c>(&'c mut self) -> FnLowerCtx<'c, 'b> {
FnLowerCtx {
b: self.b,
instructions: Vec::new(),
generics: self.generics,
var_stack: self.var_stack,
output: self.output,
origin: self.origin,
@@ -129,3 +149,17 @@ impl<'a, 'b> FnLowerCtx<'a, 'b> {
}
}
}
impl<'b> Deref for FnLowerCtx<'_, 'b> {
type Target = UModuleBuilder<'b>;
fn deref(&self) -> &Self::Target {
self.b
}
}
impl DerefMut for FnLowerCtx<'_, '_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.b
}
}
+22
View File
@@ -0,0 +1,22 @@
use std::collections::HashMap;
use crate::{ir::VarInstID, parser::PMap};
use super::{FnLowerCtx, FnLowerable};
impl FnLowerable for PMap {
type Output = HashMap<String, VarInstID>;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
Some(
self.0
.iter()
.flat_map(|n| {
let def = n.as_ref()?;
let name = def.name.as_ref()?.to_string();
let expr = def.val.as_ref()?.lower(ctx)?;
Some((name, expr))
})
.collect(),
)
}
}
+1
View File
@@ -6,6 +6,7 @@ mod expr;
mod func;
mod struc;
mod ty;
mod map;
use super::*;
use crate::ir::{Type, UFunc, UModuleBuilder};
+8 -43
View File
@@ -1,52 +1,18 @@
use crate::{
common::{CompilerOutput, FileSpan},
ir::{StructField, StructID, UInstruction, UModuleBuilder, UProgram, UStruct, VarInst},
parser::{Node, PMap, PStruct, PStructFields},
ir::{StructField, StructID, UModuleBuilder, UProgram, UStruct},
parser::{Node, PStruct, PStructFields},
};
use super::{FnLowerCtx, FnLowerable};
impl FnLowerable for PMap {
type Output = VarInst;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
let ty = self.name.lower(ctx.b, ctx.output);
let fields = match &self.fields {
PConstructFields::Named(nodes) => nodes
.iter()
.flat_map(|n| {
let def = n.as_ref()?;
let name = def.name.as_ref()?.to_string();
let expr = def.val.as_ref()?.lower(ctx)?;
Some((name, expr))
})
.collect(),
PConstructFields::Tuple(nodes) => nodes
.iter()
.enumerate()
.flat_map(|(i, n)| {
let expr = n.as_ref()?.lower(ctx)?;
let name = format!("{i}");
Some((name, expr))
})
.collect(),
PConstructFields::None => Default::default(),
};
let id = ctx.temp(ty);
ctx.push(UInstruction::Construct { dst: id, fields });
Some(id)
}
}
impl PStruct {
pub fn lower(
&self,
id: StructID,
p: &mut UModuleBuilder,
b: &mut UModuleBuilder,
output: &mut CompilerOutput,
span: FileSpan,
) -> Option<()> {
p.push();
let generics = self.generics.iter().flat_map(|a| a.lower(p)).collect();
let generics = self.generics.iter().flat_map(|a| a.lower(b)).collect();
let fields = match &self.fields {
PStructFields::Named(nodes) => nodes
.iter()
@@ -54,7 +20,7 @@ impl PStruct {
let def = n.as_ref()?;
let name = def.name.as_ref()?.to_string();
let tynode = def.ty.as_ref()?;
let ty = tynode.lower(p, output);
let ty = tynode.lower(b, output);
Some((name, ty))
})
.collect(),
@@ -62,7 +28,7 @@ impl PStruct {
.iter()
.enumerate()
.flat_map(|(i, n)| {
let ty = n.as_ref()?.lower(p, output, span);
let ty = n.as_ref()?.lower(b, output, span);
Some((format!("{i}"), ty))
})
.collect(),
@@ -72,13 +38,12 @@ impl PStruct {
.map(|(name, ty)| (name, StructField { ty }))
.collect();
let name = self.name.as_ref()?.to_string();
p.def_data(UStruct {
b.def_data(UStruct {
name,
generics,
gargs: generics,
fields,
origin: span,
});
p.pop();
Some(())
}
}
+10 -7
View File
@@ -54,7 +54,7 @@ impl PType {
name: id.0.clone(),
origin,
});
let ty = Type::Unres(ModPath { m: p.module, path });
let ty = Type::Unres(ModPath { id: p.module, path });
return p.def_ty(ty);
}
let ty = match ty {
@@ -65,7 +65,7 @@ impl PType {
origin,
});
path.reverse();
Type::Unres(ModPath { m: p.module, path })
Type::Unres(ModPath { id: p.module, path })
}
PType::Ref(node) => node.lower(p, output).rf(),
PType::Generic(node, nodes) => todo!(),
@@ -75,12 +75,15 @@ impl PType {
}
impl Node<PGenericDef> {
pub fn lower(&self, p: &mut UProgram) -> Option<GenericID> {
pub fn lower(&self, p: &mut UProgram) -> Option<(String, GenericID)> {
let s = self.as_ref()?;
let name = s.name.as_ref()?.to_string();
Some(p.def_generic(UGeneric {
name,
origin: self.origin,
}))
Some((
name.clone(),
p.def_generic(UGeneric {
name,
origin: self.origin,
}),
))
}
}
+3 -3
View File
@@ -1,13 +1,13 @@
use super::{
util::parse_list, Node, PBlock, PIdent, PType, PVarDef, Parsable, ParseResult, ParserCtx,
Symbol,
util::parse_list, Node, PBlock, PGenericDef, PIdent, PType, PVarDef, Parsable, ParseResult,
ParserCtx, Symbol,
};
use std::fmt::Debug;
pub struct PFunctionHeader {
pub name: Node<PIdent>,
pub args: Vec<Node<PVarDef>>,
pub gargs: Vec<Node<PType>>,
pub gargs: Vec<Node<PGenericDef>>,
pub ret: Option<Node<PType>>,
}
+1 -1
View File
@@ -14,7 +14,7 @@ pub struct PStruct {
pub fields: PStructFields,
}
pub struct PMap(Vec<Node<PFieldDef>>);
pub struct PMap(pub Vec<Node<PFieldDef>>);
#[derive(Debug)]
pub enum PStructFields {