moving to desktop

This commit is contained in:
2025-05-02 22:03:32 -04:00
parent 57c46b653e
commit 5f36be9de9
19 changed files with 197 additions and 236 deletions

View File

@@ -1,6 +1,8 @@
use std::collections::HashMap;
use crate::ir::{AsmBlockArgType, Size, StructTy, SymbolSpace, Type, UFunc, UInstrInst, VarOffset};
use crate::ir::{
AsmBlockArgType, FnID, Size, GenericTy, SymbolSpace, Type, UFunc, UInstrInst, VarOffset,
};
use super::{
IRLFunction, LInstruction, Len, Symbol, SymbolSpaceBuilder, UInstruction, UProgram, VarID,
@@ -14,15 +16,11 @@ pub struct LProgram {
// NOTE: there are THREE places here where I specify size (8)
impl LProgram {
pub fn create(p: &UProgram) -> Result<Self, String> {
let start = p
.names
.id::<UFunc>(&[], "crate")
.ok_or("no start method found")?;
pub fn create(p: &UProgram, start: FnID) -> Result<Self, String> {
let mut ssbuilder = SymbolSpaceBuilder::with_entries(&[start]);
let entry = ssbuilder.func(&start);
while let Some((sym, i)) = ssbuilder.pop_fn() {
let f = p.fns[i.0].as_ref().unwrap();
let f = &p.fns[i];
let mut fbuilder = LFunctionBuilder::new(p, &mut ssbuilder);
for i in &f.instructions {
fbuilder.insert_instr(i);
@@ -31,7 +29,7 @@ impl LProgram {
fbuilder.instrs.push(LInstruction::Ret { src: None });
}
let res = fbuilder.finish(f);
ssbuilder.write_fn(sym, res, Some(p.names.path(i).to_string()));
ssbuilder.write_fn(sym, res, Some(f.name.clone()));
}
let sym_space = ssbuilder.finish().expect("we failed the mission");
Ok(Self { sym_space, entry })
@@ -376,7 +374,7 @@ impl LFunctionBuilderData<'_> {
pub fn addr_size(&self) -> Size {
64
}
pub fn struct_inst(&mut self, p: &UProgram, ty: &StructTy) -> &StructInst {
pub fn struct_inst(&mut self, p: &UProgram, ty: &GenericTy) -> &StructInst {
// normally I'd let Some(..) here and return, but polonius does not exist :grief:
if self.struct_insts.get(ty).is_none() {
let StructInst { id, args } = ty;

View File

@@ -1,22 +0,0 @@
use crate::common::{CompilerMsg, CompilerOutput, FileSpan};
use super::{UProgram, Type};
impl CompilerOutput {
pub fn check_assign(&mut self, p: &UProgram, src: &Type, dest: &Type, span: FileSpan) {
// TODO: spans
if src != dest {
if !src.is_resolved() || !dest.is_resolved() {
return;
}
self.err(CompilerMsg {
msg: format!(
"Cannot assign type '{}' to '{}'",
p.type_name(src),
p.type_name(dest)
),
spans: vec![span],
});
}
}
}

View File

@@ -1,26 +1,33 @@
use crate::ir::VarID;
use std::fmt::Debug;
use super::{Origin, UInstruction};
use super::{MemberID, ModPath, Origin, UInstruction};
#[derive(Clone, Copy)]
#[derive(Clone)]
pub struct VarInst {
pub id: VarID,
pub status: VarStatus,
pub origin: Origin,
}
#[derive(Clone)]
pub enum VarStatus {
Res(VarID),
Unres { mid: ModPath, fields: Vec<MemberID> },
Partial { v: VarID, fields: Vec<MemberID> },
}
#[derive(Clone)]
pub struct VarParent {
id: VarID,
path: Vec<String>,
}
#[derive(Clone)]
pub struct UInstrInst {
pub i: UInstruction,
pub origin: Origin,
}
impl Debug for VarInst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.id)
}
}
impl Debug for UInstrInst {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self.i)

View File

@@ -73,7 +73,8 @@ impl std::fmt::Debug for UInstruction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Mv { dst: dest, src } => write!(f, "{dest:?} <- {src:?}")?,
Self::Ref { dst: dest, src } => write!(f, "{dest:?} <- &{src:?}")?,
Self::Ref { dst: dest, src } => write!(f, "{dest:?} <- {src:?}&")?,
Self::Deref { dst: dest, src } => write!(f, "{dest:?} <- {src:?}^")?,
Self::LoadData { dst: dest, src } => write!(f, "{dest:?} <- {src:?}")?,
Self::LoadFn { dst: dest, src } => write!(f, "{dest:?} <- {src:?}")?,
Self::LoadSlice { dst: dest, src } => write!(f, "{dest:?} <- &[{src:?}]")?,

View File

@@ -1,4 +1,4 @@
use super::{Type, UInstrInst, UInstruction, UProgram};
use super::{Type, UInstrInst, UInstruction};
use crate::{
common::FileSpan,
ir::{Len, ID},
@@ -12,7 +12,7 @@ pub struct UFunc {
pub name: String,
pub origin: Origin,
pub args: Vec<VarID>,
pub argtys: Vec<TypeID>,
pub gargs: Vec<TypeID>,
pub ret: TypeID,
pub instructions: Vec<UInstrInst>,
}
@@ -41,13 +41,8 @@ pub struct UVar {
pub name: String,
pub origin: Origin,
pub ty: TypeID,
pub res: UVarTy,
}
#[derive(Clone)]
pub struct VarParent {
id: VarID,
path: Vec<String>,
pub parent: Option<VarID>,
pub children: Vec<VarID>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
@@ -62,25 +57,6 @@ pub struct ModPath {
pub path: Vec<MemberID>,
}
#[derive(Clone)]
pub enum UVarTy {
Ptr(VarID),
/// fully resolved & typed
Res {
parent: Option<VarParent>,
},
/// module doesn't exist yet
Unres {
path: ModPath,
fields: Vec<MemberID>,
},
/// parent var exists but not typed enough for this field path
Partial {
v: VarID,
fields: Vec<MemberID>,
},
}
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
pub struct VarOffset {
pub id: VarID,
@@ -117,12 +93,6 @@ pub enum Member {
pub type Origin = FileSpan;
impl UFunc {
pub fn ty(&self, program: &UProgram) -> Type {
Type::Fn {
args: self.argtys.clone(),
ret: Box::new(self.ret.clone()),
}
}
pub fn flat_iter(&self) -> impl Iterator<Item = &UInstrInst> {
InstrIter::new(self.instructions.iter())
}

View File

@@ -1,5 +1,4 @@
mod assoc;
mod error;
mod inst;
mod instr;
mod kind;
@@ -11,7 +10,6 @@ mod resolve;
use super::*;
use assoc::*;
pub use assoc::Idents;
pub use inst::*;
pub use instr::*;
pub use kind::*;

View File

@@ -12,6 +12,11 @@ pub struct UProgram {
pub generics: Vec<UGeneric>,
pub vars: Vec<UVar>,
pub types: Vec<Type>,
pub unres_vars: Vec<VarID>,
pub unres_tys: Vec<TypeID>,
pub unit: TypeID,
pub error: TypeID,
}
pub struct UModuleBuilder<'a> {
@@ -22,6 +27,9 @@ pub struct UModuleBuilder<'a> {
impl UProgram {
pub fn new() -> Self {
let mut types = Vec::new();
let unit = Self::push_id(&mut types, Type::Unit);
let error = Self::push_id(&mut types, Type::Error);
Self {
fns: Vec::new(),
vars: Vec::new(),
@@ -30,24 +38,36 @@ impl UProgram {
generics: Vec::new(),
data: Vec::new(),
modules: Vec::new(),
unres_vars: Vec::new(),
unres_tys: Vec::new(),
error,
unit,
}
}
pub fn instantiate_type(&mut self, ty: Type) {
self.def_ty(match ty {
Type::Ref(node) => Type::Ref(node.lower()),
Type::Generic(node, nodes) => todo!(),
Type::Ident(node) => todo!(),
});
pub fn inst_type(&mut self, ty: TypeID, gs: Vec<TypeID>) -> TypeID {
let ty = match &self.types[ty] {
Type::Ref(id) => Type::Ref(self.inst_type(*id, gs)),
Type::Generic(id) => return gs[id.0],
Type::Bits(b) => Type::Bits(*b),
Type::Struct(struct_ty) => Type::Struct(struct_ty.clone()),
Type::Fn() => todo!(),
Type::Deref(id) => todo!(),
Type::Slice(id) => todo!(),
Type::Array(id, _) => todo!(),
Type::Unit => todo!(),
Type::Unres(mod_path) => todo!(),
Type::Infer => todo!(),
Type::Error => todo!(),
};
self.def_ty(ty)
}
pub fn infer(&mut self) -> TypeID {
self.def_ty(Type::Infer)
}
pub fn error(&mut self) -> TypeID {
self.def_ty(Type::Error)
}
pub fn set_type(id: TypeID, ty: Type) {}
pub fn def_var(&mut self, v: UVar) -> VarID {
Self::push_id(&mut self.vars, v)

View File

@@ -1,4 +1,4 @@
use super::{Origin, StructTy, Type, TypeID, TypeIDed, UInstruction, UProgram, UStruct, UVar};
use super::{Origin, GenericTy, Type, TypeID, TypeIDed, UInstruction, UProgram, UStruct, UVar};
use crate::common::{CompilerMsg, CompilerOutput};
use std::{collections::HashMap, ops::BitOrAssign};
@@ -65,10 +65,6 @@ impl UProgram {
format!("Type of {:?} cannot be inferred", var.name),
var.origin,
)),
Type::Placeholder => output.err(CompilerMsg::new(
format!("Var {:?} still placeholder!", var.name),
var.origin,
)),
Type::Unres(_) => output.err(CompilerMsg::new(
format!("Var {:?} type still unresolved!", var.name),
var.origin,
@@ -91,11 +87,12 @@ pub fn resolve_instr(data: &mut ResData, i: &UInstruction) -> InstrRes {
let mut uf = InstrRes::Finished;
match &i {
UInstruction::Call { dst, f, args } => {
let fty = data.vars[f.id].ty;
let Type::Fn { args: fargs, ret } = &data.types[fty] else {
let ftyid = data.vars[f.id].ty;
let fty = &data.types[ftyid];
let Type::Fn { args: fargs, ret } = fty else {
data.errs.push(ResErr::NotCallable {
origin: f.origin,
ty: fty,
ty: ftyid,
});
return InstrRes::Finished;
};
@@ -131,7 +128,7 @@ pub fn resolve_instr(data: &mut ResData, i: &UInstruction) -> InstrRes {
let dest_ty = get(vars, dst.id)?;
let Type::Struct(sty) = dest_ty else {};
let id = sty.id;
let Some(struc) = self.get(id) else {};
let Some(struc) = get(id) else {};
let mut new = HashMap::new();
for (name, field) in &struc.fields {
let Some(src) = fields.get(name) else {
@@ -155,7 +152,7 @@ pub fn resolve_instr(data: &mut ResData, i: &UInstruction) -> InstrRes {
args[i] = ty;
}
}
set(vars, dst.id, Type::Struct(StructTy { id, args }));
set(vars, dst.id, Type::Struct(GenericTy { id, args }));
}
UInstruction::If { cond, body } => {
for i in body {

View File

@@ -1,4 +1,5 @@
use super::{FnID, GenericID, Len, ModPath, StructID, TypeID, UVar, VarID, VarInst};
use super::{GenericID, Len, ModPath, TypeID, UFunc, UProgram, UStruct, UVar, VarID, VarInst};
use crate::ir::ID;
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub struct FieldRef {
@@ -7,16 +8,16 @@ pub struct FieldRef {
}
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct StructTy {
pub id: StructID,
pub struct GenericTy<T> {
pub id: ID<T>,
pub args: Vec<TypeID>,
}
#[derive(Clone)]
pub enum Type {
Bits(u32),
Struct(StructTy),
Fn(FnID),
Struct(GenericTy<UStruct>),
Fn(GenericTy<UFunc>),
Ref(TypeID),
Deref(TypeID),
Slice(TypeID),
@@ -27,7 +28,21 @@ pub enum Type {
Generic(GenericID),
Infer,
Error,
Placeholder,
}
impl Type {
pub fn rf(self, p: &mut UProgram) -> Self {
p.def_ty(self).rf()
}
pub fn derf(self, p: &mut UProgram) -> Self {
p.def_ty(self).derf()
}
pub fn arr(self, p: &mut UProgram, len: Len) -> Self {
p.def_ty(self).arr(len)
}
pub fn slice(self, p: &mut UProgram) -> Self {
p.def_ty(self).slice()
}
}
impl TypeID {
@@ -46,9 +61,6 @@ impl TypeID {
}
impl Type {
pub fn is_resolved(&self) -> bool {
!matches!(self, Self::Error | Self::Placeholder | Self::Infer)
}
pub fn bx(self) -> Box<Self> {
Box::new(self)
}