moving to desktop
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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:?}]")?,
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user