getting closer

This commit is contained in:
2025-05-04 14:21:27 -04:00
parent 6583d47ef8
commit 9368d6dcd0
16 changed files with 423 additions and 327 deletions

View File

@@ -1,10 +1,10 @@
use crate::{compiler::arch::riscv::*, ir::VarInst}; use crate::{compiler::arch::riscv::*, ir::UIdent};
pub type RV64Instruction = LinkerInstruction<RegRef, VarInst>; pub type RV64Instruction = LinkerInstruction<RegRef, UIdent>;
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum RegRef { pub enum RegRef {
Var(VarInst), Var(UIdent),
Reg(Reg), Reg(Reg),
} }

View File

@@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::ir::{AsmBlockArgType, Size, StructTy, SymbolSpace, Type, UFunc, UInstrInst, VarOffset}; use crate::ir::{AsmBlockArgType, Size, LStructInst, SymbolSpace, Type, UFunc, UInstrInst, VarOffset};
StructTy LStructInst
use super::{ use super::{
IRLFunction, LInstruction, Len, Symbol, SymbolSpaceBuilder, UInstruction, UProgram, VarID, IRLFunction, LInstruction, Len, Symbol, SymbolSpaceBuilder, UInstruction, UProgram, VarID,
}; };
@@ -42,14 +42,14 @@ impl LProgram {
} }
} }
pub struct StructInst { pub struct LStructInst {
offsets: Vec<Len>, offsets: Vec<Len>,
types: Vec<Type>, types: Vec<Type>,
order: HashMap<String, usize>, order: HashMap<String, usize>,
size: Size, size: Size,
} }
impl StructInst { impl LStructInst {
pub fn offset(&self, name: &str) -> Option<Len> { pub fn offset(&self, name: &str) -> Option<Len> {
Some(self.offsets[*self.order.get(name)?]) Some(self.offsets[*self.order.get(name)?])
} }
@@ -82,7 +82,7 @@ pub struct LFunctionBuilderData<'a> {
instrs: Vec<LInstruction>, instrs: Vec<LInstruction>,
stack: HashMap<VarID, Size>, stack: HashMap<VarID, Size>,
subvar_map: HashMap<VarID, VarOffset>, subvar_map: HashMap<VarID, VarOffset>,
struct_insts: HashMap<StructInst, StructInst>, struct_insts: HashMap<LStructInst, LStructInst>,
makes_call: bool, makes_call: bool,
loopp: Option<LoopCtx>, loopp: Option<LoopCtx>,
} }
@@ -376,10 +376,10 @@ impl LFunctionBuilderData<'_> {
pub fn addr_size(&self) -> Size { pub fn addr_size(&self) -> Size {
64StructTy 64StructTy
} }
pub fn struct_inst(&mut self, p: &UProgram, ty: &StructTy) -> &StructInst { pub fn struct_inst(&mut self, p: &UProgram, ty: &LStructInst) -> &LStructInst {
// normally I'd let Some(..) here and return, but polonius does not exist :grief: // normally I'd let Some(..) here and return, but polonius does not exist :grief:
if self.struct_insts.get(ty).is_none() { if self.struct_insts.get(ty).is_none() {
let StructInst { id, args } = ty; let LStructInst { id, args } = ty;
let struc = p.expect(*id); let struc = p.expect(*id);
let mut types = Vec::new(); let mut types = Vec::new();
let mut sizes = struc let mut sizes = struc
@@ -412,7 +412,7 @@ impl LFunctionBuilderData<'_> {
} }
self.struct_insts.insert( self.struct_insts.insert(
ty.clone(), ty.clone(),
StructInst { LStructInst {
offsets, offsets,
order, order,
types, types,
@@ -423,7 +423,7 @@ impl LFunctionBuilderData<'_> {
self.struct_insts.get(ty).unwrap() self.struct_insts.get(ty).unwrap()
} }
pub fn field_offset(&mut self, p: &UProgram, sty: &StructInst, field: &str) -> Option<Len> { pub fn field_offset(&mut self, p: &UProgram, sty: &LStructInst, field: &str) -> Option<Len> {
let inst = self.struct_inst(p, sty); let inst = self.struct_inst(p, sty);
Some(inst.offset(field)?) Some(inst.offset(field)?)
} }

View File

@@ -3,7 +3,7 @@ use crate::{
ir::ID, ir::ID,
}; };
use super::{KindTy, Origin, StructID, TypeID, UProgram}; use super::{KindTy, Origin, Res, StructID, TypeID, UProgram};
pub fn report_errs(p: &UProgram, output: &mut CompilerOutput, errs: Vec<ResErr>) { pub fn report_errs(p: &UProgram, output: &mut CompilerOutput, errs: Vec<ResErr>) {
for err in errs { for err in errs {
@@ -82,18 +82,18 @@ pub fn report_errs(p: &UProgram, output: &mut CompilerOutput, errs: Vec<ResErr>)
origin, origin,
found, found,
expected, expected,
id,
} => output.err(CompilerMsg::new( } => output.err(CompilerMsg::new(
{ {
let name = match found { let name = match &found {
KindTy::Type => &p.type_name(ID::new(id)), Res::Fn(fty) => &p.fns[fty.id].name,
KindTy::Var => &p.vars[id].name, Res::Type(id) => &p.type_name(id),
KindTy::Struct => &p.structs[id].name, Res::Var(id) => &p.vars[id].name,
Res::Struct(sty) => &p.structs[sty.id].name,
}; };
format!( format!(
"Expected {}, found {} '{}'", "Expected {}, found {} '{}'",
expected.str(), expected.str(),
found.str(), found.kind_str(),
name name
) )
}, },
@@ -106,12 +106,20 @@ pub fn report_errs(p: &UProgram, output: &mut CompilerOutput, errs: Vec<ResErr>)
} }
} }
#[derive(Debug, Clone)]
pub enum ResErr { pub enum ResErr {
UnknownModule {
origin: Origin,
name: String,
},
UnknownMember {
origin: Origin,
name: String,
},
KindMismatch { KindMismatch {
origin: Origin, origin: Origin,
expected: KindTy, expected: KindTy,
found: KindTy, found: Res,
id: usize,
}, },
UnexpectedField { UnexpectedField {
origin: Origin, origin: Origin,
@@ -158,6 +166,7 @@ pub enum ResErr {
}, },
} }
#[derive(Debug, Clone)]
pub enum ControlFlowOp { pub enum ControlFlowOp {
Break, Break,
Continue, Continue,
@@ -172,6 +181,7 @@ impl ControlFlowOp {
} }
} }
#[derive(Debug, Clone)]
pub struct TypeMismatch { pub struct TypeMismatch {
pub dst: TypeID, pub dst: TypeID,
pub src: TypeID, pub src: TypeID,

View File

@@ -1,53 +1,53 @@
use std::{collections::HashMap, fmt::Write}; use std::{collections::HashMap, fmt::Write};
use super::{arch::riscv64::RV64Instruction, DataID, FnID, Origin, UFunc, VarInst, VarInstID}; use super::{arch::riscv64::RV64Instruction, DataID, FnID, Origin, UFunc, UIdent, IdentID};
use crate::{compiler::arch::riscv::Reg, util::Padder}; use crate::{compiler::arch::riscv::Reg, util::Padder};
#[derive(Clone)] #[derive(Clone)]
pub enum UInstruction { pub enum UInstruction {
Mv { Mv {
dst: VarInstID, dst: IdentID,
src: VarInstID, src: IdentID,
}, },
Ref { Ref {
dst: VarInstID, dst: IdentID,
src: VarInstID, src: IdentID,
}, },
Deref { Deref {
dst: VarInstID, dst: IdentID,
src: VarInstID, src: IdentID,
}, },
LoadData { LoadData {
dst: VarInstID, dst: IdentID,
src: DataID, src: DataID,
}, },
LoadSlice { LoadSlice {
dst: VarInstID, dst: IdentID,
src: DataID, src: DataID,
}, },
LoadFn { LoadFn {
dst: VarInstID, dst: IdentID,
src: FnID, src: FnID,
}, },
Call { Call {
dst: VarInstID, dst: IdentID,
f: VarInstID, f: IdentID,
args: Vec<VarInstID>, args: Vec<IdentID>,
}, },
AsmBlock { AsmBlock {
instructions: Vec<RV64Instruction>, instructions: Vec<RV64Instruction>,
args: Vec<AsmBlockArg>, args: Vec<AsmBlockArg>,
}, },
Ret { Ret {
src: VarInstID, src: IdentID,
}, },
Construct { Construct {
dst: VarInstID, dst: IdentID,
struc: VarInstID, struc: IdentID,
fields: HashMap<String, VarInstID>, fields: HashMap<String, IdentID>,
}, },
If { If {
cond: VarInstID, cond: IdentID,
body: Vec<UInstrInst>, body: Vec<UInstrInst>,
}, },
Loop { Loop {
@@ -71,7 +71,7 @@ impl std::fmt::Debug for UInstrInst {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct AsmBlockArg { pub struct AsmBlockArg {
pub var: VarInstID, pub var: IdentID,
pub reg: Reg, pub reg: Reg,
pub ty: AsmBlockArgType, pub ty: AsmBlockArgType,
} }

View File

@@ -1,4 +1,4 @@
use super::{Type, UInstrInst, UInstruction}; use super::{FnInst, ResErr, StructInst, Type, UInstrInst, UInstruction};
use crate::{ use crate::{
common::FileSpan, common::FileSpan,
ir::{Len, ID}, ir::{Len, ID},
@@ -7,57 +7,9 @@ use std::{collections::HashMap, fmt::Debug};
pub type NamePath = Vec<String>; pub type NamePath = Vec<String>;
// "effective" (externally visible) kinds
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KindTy {
Type,
Var,
Struct,
Fn,
}
impl KindTy {
pub fn str(&self) -> &'static str {
match self {
KindTy::Type => "type",
KindTy::Var => "variable",
KindTy::Fn => "function",
KindTy::Struct => "struct",
}
}
}
pub trait Kind {
fn ty() -> KindTy;
}
impl Kind for UFunc {
fn ty() -> KindTy {
KindTy::Fn
}
}
impl Kind for UVar {
fn ty() -> KindTy {
KindTy::Var
}
}
impl Kind for UStruct {
fn ty() -> KindTy {
KindTy::Struct
}
}
impl Kind for Type {
fn ty() -> KindTy {
KindTy::Type
}
}
pub type FnID = ID<UFunc>; pub type FnID = ID<UFunc>;
pub type VarID = ID<UVar>; pub type VarID = ID<UVar>;
pub type VarInstID = ID<VarInst>; pub type IdentID = ID<UIdent>;
pub type TypeID = ID<Type>; pub type TypeID = ID<Type>;
pub type GenericID = ID<UGeneric>; pub type GenericID = ID<UGeneric>;
pub type StructID = ID<UStruct>; pub type StructID = ID<UStruct>;
@@ -99,31 +51,33 @@ pub struct UVar {
pub origin: Origin, pub origin: Origin,
pub ty: TypeID, pub ty: TypeID,
pub parent: Option<VarID>, pub parent: Option<VarID>,
pub children: Vec<VarID>, pub children: HashMap<String, VarID>,
} }
/// these are more like "expressions", need to find good name
/// eg. a::b::c::<T,U>.d.e /// eg. a::b::c::<T,U>.d.e
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct VarInst { pub struct UIdent {
pub status: VarStatus, pub status: IdentStatus,
pub origin: Origin, pub origin: Origin,
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum VarStatus { pub enum IdentStatus {
Var(VarID), Var(VarID),
Struct(StructID, Vec<TypeID>), Struct(StructInst),
Fn(FnInst),
Type(TypeID),
Unres { Unres {
path: ModPath, path: ModPath,
name: String, mem: MemberID,
gargs: Vec<TypeID>, gargs: Vec<TypeID>,
fields: Vec<MemberID>, fields: Vec<MemberID>,
}, },
Partial { PartialVar {
v: VarID, id: VarID,
fields: Vec<MemberID>, fields: Vec<MemberID>,
}, },
Failed(ResErr),
Cooked, Cooked,
} }
@@ -209,13 +163,3 @@ impl<'a> Iterator for InstrIter<'a> {
} }
} }
impl VarInst {
pub fn id(&self) -> Option<VarID> {
match &self.status {
VarStatus::Var(id) => Some(*id),
VarStatus::Unres { .. } => None,
VarStatus::Partial { .. } => None,
VarStatus::Cooked => None,
}
}
}

View File

@@ -12,3 +12,4 @@ pub use kind::*;
pub use program::*; pub use program::*;
pub use ty::*; pub use ty::*;
pub use error::*; pub use error::*;
pub use resolve::*;

View File

@@ -11,7 +11,7 @@ pub struct UProgram {
pub data: Vec<UData>, pub data: Vec<UData>,
pub generics: Vec<UGeneric>, pub generics: Vec<UGeneric>,
pub vars: Vec<UVar>, pub vars: Vec<UVar>,
pub vars_insts: Vec<VarInst>, pub idents: Vec<UIdent>,
pub types: Vec<Type>, pub types: Vec<Type>,
pub vfmap: HashMap<VarID, FnID>, pub vfmap: HashMap<VarID, FnID>,
@@ -39,7 +39,7 @@ impl UProgram {
Self { Self {
fns: Vec::new(), fns: Vec::new(),
vars: Vec::new(), vars: Vec::new(),
vars_insts: Vec::new(), idents: Vec::new(),
structs: Vec::new(), structs: Vec::new(),
types: Vec::new(), types: Vec::new(),
generics: Vec::new(), generics: Vec::new(),
@@ -66,8 +66,8 @@ impl UProgram {
push_id(&mut self.types, t) push_id(&mut self.types, t)
} }
pub fn def_var_inst(&mut self, i: VarInst) -> VarInstID { pub fn def_var_inst(&mut self, i: UIdent) -> IdentID {
push_id(&mut self.vars_insts, i) push_id(&mut self.idents, i)
} }
pub fn def_generic(&mut self, g: UGeneric) -> GenericID { pub fn def_generic(&mut self, g: UGeneric) -> GenericID {
@@ -85,12 +85,12 @@ impl UProgram {
pub fn type_name(&self, ty: impl Typed) -> String { pub fn type_name(&self, ty: impl Typed) -> String {
match ty.ty(self) { match ty.ty(self) {
Type::Struct(ty) => { Type::Struct(ty) => {
format!("{}{}", self.structs[ty.id].name, self.gparams_str(&ty.args)) format!("{}{}", self.structs[ty.id].name, self.gparams_str(&ty.gargs))
} }
Type::FnRef(ty) => { Type::FnRef(ty) => {
format!( format!(
"fn{}({}) -> {}", "fn{}({}) -> {}",
&self.gparams_str(&ty.args), &self.gparams_str(&ty.gargs),
&self.type_list_str(self.fns[ty.id].args.iter().map(|v| self.vars[v].ty)), &self.type_list_str(self.fns[ty.id].args.iter().map(|v| self.vars[v].ty)),
&self.type_name(self.fns[ty.id].ret) &self.type_name(self.fns[ty.id].ret)
) )
@@ -146,21 +146,21 @@ impl<'a> UModuleBuilder<'a> {
temp: 0, temp: 0,
} }
} }
pub fn temp_var(&mut self, origin: Origin, ty: impl Typable) -> VarInstID { pub fn temp_var(&mut self, origin: Origin, ty: impl Typable) -> IdentID {
self.temp_var_inner(origin, ty) self.temp_var_inner(origin, ty)
} }
fn temp_var_inner(&mut self, origin: Origin, ty: impl Typable) -> VarInstID { fn temp_var_inner(&mut self, origin: Origin, ty: impl Typable) -> IdentID {
let var = UVar { let var = UVar {
name: format!("temp{}", self.temp), name: format!("temp{}", self.temp),
ty: ty.ty(self), ty: ty.ty(self),
origin, origin,
parent: None, parent: None,
children: Vec::new(), children: HashMap::new(),
}; };
let id = self.p.def_var(var); let id = self.p.def_var(var);
self.temp += 1; self.temp += 1;
self.def_var_inst(VarInst { self.def_var_inst(UIdent {
status: VarStatus::Var(id), status: IdentStatus::Var(id),
origin, origin,
}) })
} }

View File

@@ -1,9 +1,11 @@
use super::{ use super::{
report_errs, ControlFlowOp, DataID, Kind, MemberTy, Origin, ResErr, Type, TypeID, TypeMismatch, UData, UFunc, UGeneric, UInstrInst, UInstruction, UModule, UProgram, UStruct, UVar, VarID, VarInst, VarInstID, VarStatus inst_fn_ty, inst_struct_ty, report_errs, ControlFlowOp, DataID, FnInst, IdentID, IdentStatus,
MemberTy, Origin, ResErr, StructInst, Type, TypeID, TypeMismatch, UData, UFunc, UGeneric,
UIdent, UInstrInst, UInstruction, UModule, UProgram, UStruct, UVar, VarID,
}; };
use crate::{ use crate::{
common::{CompilerMsg, CompilerOutput}, common::{CompilerMsg, CompilerOutput},
ir::{inst_fn_var, inst_struct_ty, KindTy, ID}, ir::{inst_fn_var, ID},
}; };
use std::{ use std::{
collections::HashSet, collections::HashSet,
@@ -21,7 +23,7 @@ impl UProgram {
changed: false, changed: false,
types: &mut self.types, types: &mut self.types,
s: Sources { s: Sources {
insts: &mut self.vars_insts, idents: &mut self.idents,
vars: &mut self.vars, vars: &mut self.vars,
fns: &self.fns, fns: &self.fns,
structs: &self.structs, structs: &self.structs,
@@ -44,13 +46,12 @@ impl UProgram {
} }
// this currently works bc expressions create temporary variables // this currently works bc expressions create temporary variables
// although you can't do things like loop {return 3} (need to analyze control flow) // although you can't do things like loop {return 3} (need to analyze control flow)
if !matches!(data.types[f.ret], Type::Unit) { if !matches!(data.types[f.ret], Type::Unit)
if f.instructions && f.instructions
.last() .last()
.is_none_or(|i| !matches!(i.i, UInstruction::Ret { .. })) .is_none_or(|i| !matches!(i.i, UInstruction::Ret { .. }))
{ {
data.errs.push(ResErr::NoReturn { fid }); data.errs.push(ResErr::NoReturn { fid });
}
} }
} }
while !data.unfinished.is_empty() && data.changed { while !data.unfinished.is_empty() && data.changed {
@@ -60,7 +61,23 @@ impl UProgram {
resolve_instr(&mut data, ctx); resolve_instr(&mut data, ctx);
} }
} }
let errs = data.errs; let mut errs = data.errs;
for ident in &self.idents {
match &ident.status {
IdentStatus::Unres {
path,
mem,
gargs,
fields,
} => errs.push(ResErr::UnknownModule {
origin: path.path[0].origin,
name: path.path[0].name.clone(),
}),
IdentStatus::PartialVar { id, fields } => todo!(),
IdentStatus::Failed(err) => errs.push(err.clone()),
_ => (),
}
}
report_errs(self, output, errs); report_errs(self, output, errs);
for var in &self.vars { for var in &self.vars {
match &self.types[var.ty] { match &self.types[var.ty] {
@@ -93,13 +110,8 @@ pub fn resolve_instr<'a>(data: &mut ResData<'a>, ctx: ResolveCtx<'a>) -> Option<
let mut res = InstrRes::Finished; let mut res = InstrRes::Finished;
match &ctx.i.i { match &ctx.i.i {
UInstruction::Call { dst, f, args } => { UInstruction::Call { dst, f, args } => {
let fty = data.res_id(f, ctx)?; let fi = data.res_id::<UFunc>(f, ctx)?;
let Type::FnRef(ftyy) = data.types[fty].clone() else { let f = &data.s.fns[fi.id];
let origin = f.origin(data);
data.errs.push(ResErr::NotCallable { origin, ty: fty });
return None;
};
let f = &data.s.fns[ftyy.id];
for (src, dest) in args.iter().zip(&f.args) { for (src, dest) in args.iter().zip(&f.args) {
res |= data.match_types(dest, src, src); res |= data.match_types(dest, src, src);
} }
@@ -109,14 +121,14 @@ pub fn resolve_instr<'a>(data: &mut ResData<'a>, ctx: ResolveCtx<'a>) -> Option<
res |= data.match_types(dst, src, src); res |= data.match_types(dst, src, src);
} }
UInstruction::Ref { dst, src } => { UInstruction::Ref { dst, src } => {
let dstid = data.res_id(dst, ctx)?; let dstid = data.res_ty_id::<UVar>(dst, ctx)?;
let Type::Ref(dest_ty) = data.types[dstid] else { let Type::Ref(dest_ty) = data.types[dstid] else {
compiler_error() compiler_error()
}; };
res |= data.match_types(dest_ty, src, src); res |= data.match_types(dest_ty, src, src);
} }
UInstruction::Deref { dst, src } => { UInstruction::Deref { dst, src } => {
let srcid = data.res_id(src, ctx)?; let srcid = data.res_ty_id::<UVar>(src, ctx)?;
let Type::Ref(src_ty) = data.types[srcid] else { let Type::Ref(src_ty) = data.types[srcid] else {
let origin = src.origin(data); let origin = src.origin(data);
data.errs.push(ResErr::CannotDeref { origin, ty: srcid }); data.errs.push(ResErr::CannotDeref { origin, ty: srcid });
@@ -148,11 +160,8 @@ pub fn resolve_instr<'a>(data: &mut ResData<'a>, ctx: ResolveCtx<'a>) -> Option<
res |= data.match_types(ctx.ret, src, src); res |= data.match_types(ctx.ret, src, src);
} }
UInstruction::Construct { dst, struc, fields } => { UInstruction::Construct { dst, struc, fields } => {
let id = data.res_id(dst, ctx, KindTy::Struct)?; let si = data.res_id::<UStruct>(dst, ctx)?;
let Type::Struct(sty) = &data.types[id] else { let sid = si.id;
return None;
};
let sid = sty.id;
let st = &data.s.structs[sid]; let st = &data.s.structs[sid];
let mut used = HashSet::new(); let mut used = HashSet::new();
for (name, field) in &st.fields { for (name, field) in &st.fields {
@@ -180,7 +189,7 @@ pub fn resolve_instr<'a>(data: &mut ResData<'a>, ctx: ResolveCtx<'a>) -> Option<
} }
} }
UInstruction::If { cond, body } => { UInstruction::If { cond, body } => {
if let Some(id) = data.res_id(cond, ctx, KindTy::Var) { if let Some(id) = data.res_ty_id::<UVar>(cond, ctx) {
if !matches!(data.types[id], Type::Bits(64)) { if !matches!(data.types[id], Type::Bits(64)) {
let origin = cond.origin(data); let origin = cond.origin(data);
data.errs.push(ResErr::CondType { origin, ty: id }); data.errs.push(ResErr::CondType { origin, ty: id });
@@ -262,7 +271,7 @@ pub fn match_types(data: &mut TypeResData, dst: impl TypeIDed, src: impl TypeIDe
if dest.id != src.id { if dest.id != src.id {
return error(); return error();
} }
match_all(data, dest.args.iter().cloned(), src.args.iter().cloned()) match_all(data, dest.gargs.iter().cloned(), src.gargs.iter().cloned())
} }
// ( // (
// Type::Fn { // Type::Fn {
@@ -327,7 +336,7 @@ fn match_all(
} }
struct Sources<'a> { struct Sources<'a> {
insts: &'a mut [VarInst], idents: &'a mut [UIdent],
vars: &'a mut Vec<UVar>, vars: &'a mut Vec<UVar>,
fns: &'a [UFunc], fns: &'a [UFunc],
structs: &'a [UStruct], structs: &'a [UStruct],
@@ -353,12 +362,12 @@ struct TypeResData<'a> {
impl<'a> ResData<'a> { impl<'a> ResData<'a> {
pub fn match_types( pub fn match_types(
&mut self, &mut self,
dst: impl ResID<Type>, dst: impl Resolvable<Type>,
src: impl ResID<Type>, src: impl Resolvable<Type>,
origin: impl HasOrigin, origin: impl HasOrigin,
) -> InstrRes { ) -> InstrRes {
let dst = dst.try_id(&mut self.s, self.types, &mut self.errs, KindTy::Type)?; let dst = dst.try_res(&mut self.s, self.types, &mut self.errs)?;
let src = src.try_id(&mut self.s, self.types, &mut self.errs, KindTy::Type)?; let src = src.try_res(&mut self.s, self.types, &mut self.errs)?;
let res = match_types( let res = match_types(
&mut TypeResData { &mut TypeResData {
changed: &mut self.changed, changed: &mut self.changed,
@@ -382,15 +391,24 @@ impl<'a> ResData<'a> {
} }
} }
} }
pub fn try_res_id<K>(&mut self, x: impl ResID) -> Result<ID<K>, InstrRes> { pub fn try_res_id<K: ResKind>(&mut self, x: impl Resolvable<K>) -> Result<K::Res, InstrRes> {
x.try_id(&mut self.s, &mut self.types, &mut self.errs) x.try_res(&mut self.s, &mut self.types, &mut self.errs)
.map(|id| resolve_refs(self.types, id))
} }
pub fn res_id<'b: 'a, K>( pub fn res_ty_id<'b: 'a, K: ResKind>(
&mut self, &mut self,
x: impl ResID<K>, x: impl Resolvable<K>,
ctx: ResolveCtx<'b>, ctx: ResolveCtx<'b>,
) -> Option<ID<K>> { ) -> Option<TypeID>
where
K::Res: TypeIDed,
{
self.res_id::<K>(x, ctx).map(|i| i.type_id(&self.s))
}
pub fn res_id<'b: 'a, K: ResKind>(
&mut self,
x: impl Resolvable<K>,
ctx: ResolveCtx<'b>,
) -> Option<K::Res> {
match self.try_res_id(x) { match self.try_res_id(x) {
Ok(id) => return Some(id), Ok(id) => return Some(id),
Err(InstrRes::Unfinished) => self.unfinished.push(ctx), Err(InstrRes::Unfinished) => self.unfinished.push(ctx),
@@ -433,166 +451,293 @@ impl FromResidual<Option<Infallible>> for InstrRes {
} }
} }
trait ResID<K> { trait Resolvable<K: ResKind> {
fn try_id( fn try_res(
&self, &self,
s: &mut Sources, s: &mut Sources,
types: &mut Vec<Type>, types: &mut Vec<Type>,
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
) -> Result<ID<K>, InstrRes>; ) -> Result<K::Res, InstrRes>;
} }
impl<T: TypeIDed> ResID<Type> for T { impl<T: TypeIDed> Resolvable<Type> for T {
fn try_id( fn try_res(
&self, &self,
s: &mut Sources, s: &mut Sources,
_: &mut Vec<Type>, _: &mut Vec<Type>,
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
kind: KindTy,
) -> Result<TypeID, InstrRes> { ) -> Result<TypeID, InstrRes> {
Ok(self.type_id(s)) Ok(self.type_id(s))
} }
} }
impl VarInst { impl IdentID {
pub fn resolve(&mut self, s: &mut Sources) { pub fn resolve(self, s: &mut Sources) -> Result<Res, InstrRes> {
match &self.status { let ident = &mut s.idents[self];
VarStatus::Var(id) => self.status = VarStatus::Cooked, Ok(match &mut ident.status {
VarStatus::Struct(id, ids) => todo!(), IdentStatus::Var(id) => Res::Var(*id),
VarStatus::Unres { path, name, gargs, fields } => todo!(), IdentStatus::Struct(sty) => Res::Struct(sty.clone()),
VarStatus::Partial { v, fields } => todo!(), IdentStatus::Fn(fty) => Res::Fn(fty.clone()),
VarStatus::Cooked => todo!(), IdentStatus::Type(ty) => Res::Type(*ty),
} IdentStatus::Unres {
}
}
impl<K: Kind> ResID<K> for VarInstID {
fn try_id(
&self,
s: &mut Sources,
types: &mut Vec<Type>,
errs: &mut Vec<ResErr>,
) -> Result<ID<K>, InstrRes> {
let kind = K::ty();
let inst = &mut s.insts[self];
let (id, fields) = match &mut inst.status {
VarStatus::Var(id) => {
return Ok(s.vars[id].ty)
},
VarStatus::Unres {
path, path,
name, mem,
gargs, gargs,
fields, fields,
} => { } => {
let mut mid = path.id; let mut mid = path.id;
let mut depth = 0; let mut count = 0;
for mem in &path.path { for mem in &path.path {
let Some(&child) = s.modules[mid].children.get(&mem.name) else { let Some(&child) = s.modules[mid].children.get(&mem.name) else {
break; break;
}; };
depth += 1; count += 1;
mid = child; mid = child;
} }
path.path.drain(0..depth); path.path.drain(0..count);
path.id = mid; path.id = mid;
if path.path.len() != 0 { if path.path.len() != 0 {
return Err(InstrRes::Unfinished); return Err(InstrRes::Unfinished);
} }
let Some(mem) = s.modules[mid].members.get(name) else { let Some(mem) = s.modules[mid].members.get(&mem.name) else {
return Err(InstrRes::Unfinished); return Err(InstrRes::Unfinished);
}; };
let vid = match mem.id { match mem.id {
MemberTy::Fn(id) => { MemberTy::Fn(id) => {
if kind == KindTy::Fn { if fields.len() > 0 {
return Ok(id.0.into()); ident.status = IdentStatus::Failed(ResErr::UnexpectedField {
} origin: ident.origin,
if !matches!(kind, KindTy::Var | KindTy::Fn) {
errs.push(ResErr::KindMismatch {
origin: inst.origin,
expected: kind,
found: KindTy::Fn,
id: id.0,
}); });
return Err(InstrRes::Finished); return Err(InstrRes::Finished);
} }
inst_fn_var( let fty = FnInst {
id, id,
s.fns, gargs: gargs.clone(),
gargs, };
inst.origin, ident.status = IdentStatus::Fn(fty.clone());
s.vars, Res::Fn(fty)
types, }
s.generics, MemberTy::Struct(id) => {
errs, if fields.len() > 0 {
) ident.status = IdentStatus::Failed(ResErr::UnexpectedField {
origin: ident.origin,
});
return Err(InstrRes::Finished);
}
let sty = StructInst {
id,
gargs: gargs.clone(),
};
ident.status = IdentStatus::Struct(sty.clone());
Res::Struct(sty)
} }
MemberTy::Var(id) => { MemberTy::Var(id) => {
if !matches!(kind, KindTy::Var | KindTy::Any) {
errs.push(ResErr::KindMismatch {
origin: inst.origin,
expected: kind,
found: KindTy::Var,
id: id.0,
});
return Err(InstrRes::Finished);
}
if !gargs.is_empty() { if !gargs.is_empty() {
errs.push(ResErr::GenericCount { ident.status = IdentStatus::Failed(ResErr::GenericCount {
origin: inst.origin, origin: ident.origin,
expected: 0, expected: 0,
found: gargs.len(), found: gargs.len(),
}); });
}
id
}
MemberTy::Struct(id) => {
if !matches!(kind, KindTy::Struct | KindTy::Type | KindTy::Any) {
errs.push(ResErr::KindMismatch {
origin: inst.origin,
expected: kind,
found: KindTy::Struct,
id: id.0,
});
return Err(InstrRes::Finished); return Err(InstrRes::Finished);
} }
if fields.len() > 0 { ident.status = IdentStatus::PartialVar {
errs.push(ResErr::UnexpectedField { id,
origin: inst.origin, fields: fields.clone(),
}); };
return Err(InstrRes::Finished); return self.resolve(s);
}
return Ok(inst_struct_ty(
id, s.structs, gargs, types, s.generics, errs,
));
} }
};
if fields.len() > 0 {
inst.status = VarStatus::Partial{v: vid, fields}
} }
} }
VarStatus::Partial { v, fields } => (*v, fields), IdentStatus::PartialVar { id, fields } => {
VarStatus::Cooked => return Err(InstrRes::Finished), let mut fiter = fields.iter();
}; let mut next = fiter.next();
// I feel like this clone is not necessary but idk how let mut count = 0;
inst.status = VarStatus::Partial { while let Some(mem) = next
v: id, && let Some(&cid) = s.vars[*id].children.get(&mem.name)
fields: fields.clone(), {
}; *id = cid;
// let VarStatus::Partial { v, fields } = inst.status next = fiter.next();
todo!() count += 1;
}
fields.drain(0..count);
if fields.len() != 0 {
return Err(InstrRes::Unfinished);
}
let id = *id;
ident.status = IdentStatus::Var(id);
Res::Var(id)
}
IdentStatus::Cooked => return Err(InstrRes::Finished),
IdentStatus::Failed(_) => return Err(InstrRes::Finished),
})
} }
} }
impl<K> ResID<K> for &VarInstID { impl<K: ResKind> Resolvable<K> for IdentID {
fn try_id( fn try_res(
&self, &self,
s: &mut Sources, s: &mut Sources,
types: &mut Vec<Type>, types: &mut Vec<Type>,
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
kind: KindTy, ) -> Result<K::Res, InstrRes> {
) -> Result<ID<K>, InstrRes> { let origin = s.idents[self].origin;
(*self).try_id(s, types, errs, kind) let res = self.resolve(s)?;
match K::from_res(res.clone(), types, s, origin, errs) {
Some(res) => Ok(res),
None => {
errs.push(ResErr::KindMismatch {
origin,
expected: K::ty(),
found: res,
});
Err(InstrRes::Finished)
}
}
}
}
// "effective" (externally visible) kinds
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KindTy {
Type,
Var,
Struct,
Fn,
}
impl KindTy {
pub fn str(&self) -> &'static str {
match self {
KindTy::Type => "type",
KindTy::Var => "variable",
KindTy::Fn => "function",
KindTy::Struct => "struct",
}
}
}
#[derive(Debug, Clone)]
pub enum Res {
Var(VarID),
Fn(FnInst),
Struct(StructInst),
Type(TypeID),
}
impl Res {
pub fn kind(&self) -> KindTy {
match self {
Res::Var(..) => KindTy::Var,
Res::Fn(..) => KindTy::Fn,
Res::Struct(..) => KindTy::Struct,
Res::Type(..) => KindTy::Type,
}
}
pub fn kind_str(&self) -> &'static str {
self.kind().str()
}
}
pub trait ResKind {
type Res;
fn ty() -> KindTy;
fn from_res(
res: Res,
types: &mut Vec<Type>,
s: &mut Sources,
origin: Origin,
errs: &mut Vec<ResErr>,
) -> Option<Self::Res>;
}
impl ResKind for UFunc {
type Res = FnInst;
fn ty() -> KindTy {
KindTy::Fn
}
fn from_res(
res: Res,
_: &mut Vec<Type>,
_: &mut Sources,
_: Origin,
_: &mut Vec<ResErr>,
) -> Option<Self::Res> {
match res {
Res::Fn(fi) => Some(fi),
_ => None,
}
}
}
impl ResKind for UVar {
type Res = VarID;
fn ty() -> KindTy {
KindTy::Var
}
fn from_res(
res: Res,
types: &mut Vec<Type>,
s: &mut Sources,
origin: Origin,
errs: &mut Vec<ResErr>,
) -> Option<Self::Res> {
Some(match res {
Res::Fn(fty) => inst_fn_var(&fty, s.fns, origin, s.vars, types, s.generics, errs),
Res::Var(id) => id,
Res::Struct(_) => return None,
Res::Type(_) => return None,
})
}
}
impl ResKind for UStruct {
type Res = StructInst;
fn ty() -> KindTy {
KindTy::Struct
}
fn from_res(
res: Res,
_: &mut Vec<Type>,
_: &mut Sources,
_: Origin,
_: &mut Vec<ResErr>,
) -> Option<Self::Res> {
match res {
Res::Struct(si) => Some(si),
_ => None,
}
}
}
impl ResKind for Type {
type Res = TypeID;
fn ty() -> KindTy {
KindTy::Type
}
fn from_res(
res: Res,
types: &mut Vec<Type>,
s: &mut Sources,
_: Origin,
errs: &mut Vec<ResErr>,
) -> Option<Self::Res> {
Some(match res {
Res::Fn(fty) => inst_fn_ty(&fty, s.fns, types, s.generics, errs),
Res::Var(id) => id.type_id(s),
Res::Struct(si) => inst_struct_ty(&si, s.structs, types, s.generics, errs),
Res::Type(id) => id,
})
}
}
impl<K: ResKind> Resolvable<K> for &IdentID {
fn try_res(
&self,
s: &mut Sources,
types: &mut Vec<Type>,
errs: &mut Vec<ResErr>,
) -> Result<K::Res, InstrRes> {
Resolvable::<K>::try_res(*self, s, types, errs)
} }
} }
@@ -637,8 +782,8 @@ trait HasOrigin {
fn origin(&self, data: &ResData) -> Origin; fn origin(&self, data: &ResData) -> Origin;
} }
impl HasOrigin for &VarInstID { impl HasOrigin for &IdentID {
fn origin(&self, data: &ResData) -> Origin { fn origin(&self, data: &ResData) -> Origin {
data.s.insts[*self].origin data.s.idents[*self].origin
} }
} }

View File

@@ -1,8 +1,8 @@
use std::collections::HashMap; use std::collections::HashMap;
use super::{ use super::{
push_id, FnID, GenericID, Len, ModPath, Origin, ResErr, StructID, TypeCache, TypeID, UFunc, push_id, FnID, GenericID, Len, ModPath, Origin, ResErr, StructID, TypeID, UFunc, UGeneric,
UGeneric, UProgram, UStruct, UVar, VarID, UProgram, UStruct, UVar, VarID,
}; };
#[derive(Debug, Clone, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Hash, Eq, PartialEq)]
@@ -11,23 +11,23 @@ pub struct FieldRef {
pub name: String, pub name: String,
} }
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct StructTy { pub struct StructInst {
pub id: StructID, pub id: StructID,
pub args: Vec<TypeID>, pub gargs: Vec<TypeID>,
} }
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct FnTy { pub struct FnInst {
pub id: FnID, pub id: FnID,
pub args: Vec<TypeID>, pub gargs: Vec<TypeID>,
} }
#[derive(Clone)] #[derive(Clone)]
pub enum Type { pub enum Type {
Bits(u32), Bits(u32),
Struct(StructTy), Struct(StructInst),
FnRef(FnTy), FnRef(FnInst),
// this can be added for constraints later (F: fn(...) -> ...) // this can be added for constraints later (F: fn(...) -> ...)
// Fn { args: Vec<TypeID>, ret: TypeID }, // Fn { args: Vec<TypeID>, ret: TypeID },
Ref(TypeID), Ref(TypeID),
@@ -79,17 +79,16 @@ impl Type {
} }
pub fn inst_fn_var( pub fn inst_fn_var(
id: FnID, fi: &FnInst,
fns: &[UFunc], fns: &[UFunc],
gargs: &[TypeID],
origin: Origin, origin: Origin,
vars: &mut Vec<UVar>, vars: &mut Vec<UVar>,
types: &mut Vec<Type>, types: &mut Vec<Type>,
generics: &[UGeneric], generics: &[UGeneric],
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
) -> VarID { ) -> VarID {
let ty = inst_fn_ty(id, fns, gargs, types, generics, errs); let ty = inst_fn_ty(fi, fns, types, generics, errs);
let name = fns[id].name.clone(); let name = fns[fi.id].name.clone();
push_id( push_id(
vars, vars,
UVar { UVar {
@@ -97,39 +96,37 @@ pub fn inst_fn_var(
origin, origin,
ty, ty,
parent: None, parent: None,
children: Vec::new(), children: HashMap::new(),
}, },
) )
} }
pub fn inst_fn_ty( pub fn inst_fn_ty(
id: FnID, fi: &FnInst,
fns: &[UFunc], fns: &[UFunc],
gargs: &[TypeID],
types: &mut Vec<Type>, types: &mut Vec<Type>,
generics: &[UGeneric], generics: &[UGeneric],
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
) -> TypeID { ) -> TypeID {
let f = &fns[id]; let f = &fns[fi.id];
let ty = Type::FnRef(FnTy { let ty = Type::FnRef(FnInst {
id, id: fi.id,
args: inst_generics(&f.gargs, gargs, types, generics, errs), gargs: inst_generics(&f.gargs, &fi.gargs, types, generics, errs),
}); });
push_id(types, ty) push_id(types, ty)
} }
pub fn inst_struct_var( pub fn inst_struct_var(
id: StructID, si: &StructInst,
structs: &[UStruct], structs: &[UStruct],
gargs: &[TypeID],
origin: Origin, origin: Origin,
vars: &mut Vec<UVar>, vars: &mut Vec<UVar>,
types: &mut Vec<Type>, types: &mut Vec<Type>,
generics: &[UGeneric], generics: &[UGeneric],
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
) -> VarID { ) -> VarID {
let ty = inst_struct_ty(id, structs, gargs, types, generics, errs); let ty = inst_struct_ty(si, structs, types, generics, errs);
let name = structs[id].name.clone(); let name = structs[si.id].name.clone();
push_id( push_id(
vars, vars,
UVar { UVar {
@@ -137,23 +134,22 @@ pub fn inst_struct_var(
origin, origin,
ty, ty,
parent: None, parent: None,
children: Vec::new(), children: HashMap::new(),
}, },
) )
} }
pub fn inst_struct_ty( pub fn inst_struct_ty(
id: StructID, si: &StructInst,
structs: &[UStruct], structs: &[UStruct],
gargs: &[TypeID],
types: &mut Vec<Type>, types: &mut Vec<Type>,
generics: &[UGeneric], generics: &[UGeneric],
errs: &mut Vec<ResErr>, errs: &mut Vec<ResErr>,
) -> TypeID { ) -> TypeID {
let s = &structs[id]; let s = &structs[si.id];
let ty = Type::Struct(StructTy { let ty = Type::Struct(StructInst {
id, id: si.id,
args: inst_generics(&s.gargs, gargs, types, generics, errs), gargs: inst_generics(&s.gargs, &si.gargs, types, generics, errs),
}); });
push_id(types, ty) push_id(types, ty)
} }
@@ -204,18 +200,18 @@ pub fn inst_type_ins(
) -> TypeID { ) -> TypeID {
let ty = match types[id].clone() { let ty = match types[id].clone() {
Type::Bits(_) => return id, Type::Bits(_) => return id,
Type::Struct(struct_ty) => Type::Struct(StructTy { Type::Struct(struct_ty) => Type::Struct(StructInst {
id: struct_ty.id, id: struct_ty.id,
args: struct_ty gargs: struct_ty
.args .gargs
.iter() .iter()
.map(|id| inst_type(*id, types, gmap)) .map(|id| inst_type(*id, types, gmap))
.collect(), .collect(),
}), }),
Type::FnRef(fn_ty) => Type::FnRef(FnTy { Type::FnRef(fn_ty) => Type::FnRef(FnInst {
id: fn_ty.id, id: fn_ty.id,
args: fn_ty gargs: fn_ty
.args .gargs
.iter() .iter()
.map(|id| inst_type(*id, types, gmap)) .map(|id| inst_type(*id, types, gmap))
.collect(), .collect(),

View File

@@ -3,7 +3,7 @@ use crate::{
compiler::arch::riscv::*, compiler::arch::riscv::*,
ir::{ ir::{
arch::riscv64::{RV64Instruction, RegRef}, arch::riscv64::{RV64Instruction, RegRef},
VarInst, UIdent,
}, },
}; };
@@ -166,7 +166,7 @@ impl RV64Instruction {
} }
} }
pub fn arg_to_var(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<VarInst> { pub fn arg_to_var(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<UIdent> {
let PAsmArg::Ref(node) = node.inner.as_ref()? else { let PAsmArg::Ref(node) = node.inner.as_ref()? else {
ctx.err_at( ctx.err_at(
node.origin, node.origin,

View File

@@ -1,15 +1,15 @@
use crate::{ use crate::{
compiler::arch::riscv::Reg, compiler::arch::riscv::Reg,
ir::{ ir::{
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, Type, UInstruction, VarInst, arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, Type, UInstruction, UIdent,
VarInstID, IdentID,
}, },
parser::PAsmBlockArg, parser::PAsmBlockArg,
}; };
use super::{FnLowerCtx, FnLowerable, PAsmBlock, PInstruction, PUAsmBlockArg}; use super::{FnLowerCtx, FnLowerable, PAsmBlock, PInstruction, PUAsmBlockArg};
type PLAsmBlockArg = PAsmBlockArg<Reg, VarInstID>; type PLAsmBlockArg = PAsmBlockArg<Reg, IdentID>;
impl FnLowerable for PInstruction { impl FnLowerable for PInstruction {
type Output = RV64Instruction; type Output = RV64Instruction;
@@ -20,7 +20,7 @@ impl FnLowerable for PInstruction {
} }
impl FnLowerable for PAsmBlock { impl FnLowerable for PAsmBlock {
type Output = VarInstID; type Output = IdentID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> { fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
let mut args = Vec::new(); let mut args = Vec::new();

View File

@@ -1,13 +1,13 @@
use crate::{ use crate::{
ir::{Type, UInstruction, UVar, VarInst, VarInstID}, ir::{Type, UInstruction, UVar, UIdent, IdentID},
parser::{PConstStatement, PStatementLike}, parser::{PConstStatement, PStatementLike},
}; };
use super::{FnLowerCtx, FnLowerable, Import, PBlock, PStatement}; use super::{FnLowerCtx, FnLowerable, Import, PBlock, PStatement};
impl FnLowerable for PBlock { impl FnLowerable for PBlock {
type Output = VarInstID; type Output = IdentID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInstID> { fn lower(&self, ctx: &mut FnLowerCtx) -> Option<IdentID> {
let mut last = None; let mut last = None;
let mut statements = Vec::new(); let mut statements = Vec::new();
let mut fn_nodes = Vec::new(); let mut fn_nodes = Vec::new();
@@ -74,8 +74,8 @@ impl FnLowerable for PBlock {
} }
impl FnLowerable for PStatement { impl FnLowerable for PStatement {
type Output = VarInst; type Output = UIdent;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> { fn lower(&self, ctx: &mut FnLowerCtx) -> Option<UIdent> {
match self { match self {
PStatement::Let(def, e) => { PStatement::Let(def, e) => {
let def = def.lower(ctx.b, ctx.output)?; let def = def.lower(ctx.b, ctx.output)?;

View File

@@ -1,4 +1,4 @@
use crate::ir::{UProgram, UVar, VarID, VarInst}; use crate::ir::{UProgram, UVar, VarID, UIdent};
use super::{CompilerOutput, Node, PVarDef}; use super::{CompilerOutput, Node, PVarDef};
@@ -10,7 +10,7 @@ impl Node<PVarDef> {
Some(ty) => ty.lower(program, output), Some(ty) => ty.lower(program, output),
None => program.infer(self.origin), None => program.infer(self.origin),
}; };
Some(VarInst { Some(UIdent {
id: program.def_searchable(name, Some(UVar { ty }), self.origin), id: program.def_searchable(name, Some(UVar { ty }), self.origin),
origin: self.origin, origin: self.origin,
}) })

View File

@@ -1,12 +1,12 @@
use super::{func::FnLowerCtx, FnLowerable, PExpr, PostfixOp}; use super::{func::FnLowerCtx, FnLowerable, PExpr, PostfixOp};
use crate::{ use crate::{
ir::{Type, UData, UInstruction, VarInst, VarInstID}, ir::{Type, UData, UInstruction, UIdent, IdentID},
parser::InfixOp, parser::InfixOp,
}; };
impl FnLowerable for PExpr { impl FnLowerable for PExpr {
type Output = VarInstID; type Output = IdentID;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInstID> { fn lower(&self, ctx: &mut FnLowerCtx) -> Option<IdentID> {
let mut e = self; let mut e = self;
let mut path = Vec::new(); let mut path = Vec::new();
while let PExpr::Member(node, ident) = e { while let PExpr::Member(node, ident) = e {

View File

@@ -7,7 +7,7 @@ use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Imports, Node, P
use crate::{ use crate::{
ir::{ ir::{
FnID, GenericID, ModPath, Origin, Typable, Type, UFunc, UInstrInst, UInstruction, FnID, GenericID, ModPath, Origin, Typable, Type, UFunc, UInstrInst, UInstruction,
UModuleBuilder, VarID, VarInst, VarInstID, VarStatus, UModuleBuilder, VarID, UIdent, IdentID, IdentStatus,
}, },
parser, parser,
util::NameStack, util::NameStack,
@@ -68,7 +68,7 @@ impl PFunction {
let res = self.body.lower(&mut ctx); let res = self.body.lower(&mut ctx);
let mut instructions = ctx.instructions; let mut instructions = ctx.instructions;
if let Some(src) = res { if let Some(src) = res {
let origin = b.vars_insts[src].origin; let origin = b.idents[src].origin;
instructions.push(UInstrInst { instructions.push(UInstrInst {
origin, origin,
i: UInstruction::Ret { src }, i: UInstruction::Ret { src },
@@ -99,13 +99,13 @@ pub struct FnLowerCtx<'a, 'b> {
} }
impl<'a, 'b> FnLowerCtx<'a, 'b> { impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn var(&mut self, node: &Node<parser::PIdent>) -> VarInstID { pub fn var(&mut self, node: &Node<parser::PIdent>) -> IdentID {
let inst = VarInst { let inst = UIdent {
status: if let Some(n) = node.as_ref() { status: if let Some(n) = node.as_ref() {
if let Some(&var) = self.var_stack.search(&n.0) { if let Some(&var) = self.var_stack.search(&n.0) {
VarStatus::Var(var) IdentStatus::Var(var)
} else { } else {
VarStatus::Unres { IdentStatus::Unres {
path: ModPath { path: ModPath {
id: self.b.module, id: self.b.module,
path: Vec::new(), path: Vec::new(),
@@ -116,7 +116,7 @@ impl<'a, 'b> FnLowerCtx<'a, 'b> {
} }
} }
} else { } else {
VarStatus::Cooked IdentStatus::Cooked
}, },
origin: node.origin, origin: node.origin,
}; };
@@ -128,7 +128,7 @@ impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn err_at(&mut self, span: FileSpan, msg: String) { pub fn err_at(&mut self, span: FileSpan, msg: String) {
self.output.err(CompilerMsg::new(msg, span)) self.output.err(CompilerMsg::new(msg, span))
} }
pub fn temp<T: Typable>(&mut self, ty: T) -> VarInstID { pub fn temp<T: Typable>(&mut self, ty: T) -> IdentID {
self.b.temp_var(self.origin, ty) self.b.temp_var(self.origin, ty)
} }
pub fn push(&mut self, i: UInstruction) { pub fn push(&mut self, i: UInstruction) {

View File

@@ -1,11 +1,11 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{ir::VarInstID, parser::PMap}; use crate::{ir::IdentID, parser::PMap};
use super::{FnLowerCtx, FnLowerable}; use super::{FnLowerCtx, FnLowerable};
impl FnLowerable for PMap { impl FnLowerable for PMap {
type Output = HashMap<String, VarInstID>; type Output = HashMap<String, IdentID>;
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> { fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
Some( Some(
self.0 self.0