had a conversation w the code

This commit is contained in:
2025-04-25 00:37:42 -04:00
parent 329b1d86ac
commit d4edea0e62
12 changed files with 205 additions and 154 deletions

View File

@@ -75,20 +75,23 @@ fn structer(test: Test) {
println(""); println("");
} }
struct GTest<T, U> { struct GTest<T, U, V> {
a: T, a: T,
b: U, b: U,
c: V,
} }
fn generic() { fn generic() {
let gt = GTest { let gt = GTest {
a: 39, a: 39,
b: "hello", b: "hello",
c: 40,
}; };
print("generic: "); print("generic: ");
print_dec(gt.a); print_dec(gt.a);
print(", "); print(", ");
print(gt.b); print(gt.b);
print_dec(gt.c);
println(""); println("");
} }

View File

@@ -17,7 +17,7 @@ impl LProgram {
pub fn create(p: &UProgram) -> Result<Self, String> { pub fn create(p: &UProgram) -> Result<Self, String> {
let start = p let start = p
.names .names
.lookup::<UFunc>("start") .id::<UFunc>("start")
.ok_or("no start method found")?; .ok_or("no start method found")?;
let mut ssbuilder = SymbolSpaceBuilder::with_entries(&[start]); let mut ssbuilder = SymbolSpaceBuilder::with_entries(&[start]);
let entry = ssbuilder.func(&start); let entry = ssbuilder.func(&start);
@@ -31,7 +31,7 @@ impl LProgram {
fbuilder.instrs.push(LInstruction::Ret { src: None }); fbuilder.instrs.push(LInstruction::Ret { src: None });
} }
let res = fbuilder.finish(f); let res = fbuilder.finish(f);
ssbuilder.write_fn(sym, res, Some(p.names.get(i).to_string())); ssbuilder.write_fn(sym, res, Some(p.names.name(i).to_string()));
} }
let sym_space = ssbuilder.finish().expect("we failed the mission"); let sym_space = ssbuilder.finish().expect("we failed the mission");
Ok(Self { sym_space, entry }) Ok(Self { sym_space, entry })
@@ -101,7 +101,7 @@ impl<'a> LFunctionBuilder<'a> {
}; };
self.map_subvar(i); self.map_subvar(i);
let var = self.data.var_offset(self.program, i).expect("var offset"); let var = self.data.var_offset(self.program, i).expect("var offset");
if let None = self.stack.get(&var.id) { if !self.stack.contains_key(&var.id) {
let size = self let size = self
.data .data
.size_of_var(self.program, var.id) .size_of_var(self.program, var.id)
@@ -142,7 +142,7 @@ impl<'a> LFunctionBuilder<'a> {
let sym = self.data.builder.ro_data( let sym = self.data.builder.ro_data(
src, src,
&data.content, &data.content,
Some(self.program.names.get(dest.id).to_string()), Some(self.program.names.name(dest.id).to_string()),
); );
self.instrs.push(LInstruction::LoadData { self.instrs.push(LInstruction::LoadData {
dest: dest.id, dest: dest.id,
@@ -163,7 +163,7 @@ impl<'a> LFunctionBuilder<'a> {
let sym = self.data.builder.ro_data( let sym = self.data.builder.ro_data(
src, src,
&data.content, &data.content,
Some(self.program.names.get(dest.id).to_string()), Some(self.program.names.name(dest.id).to_string()),
); );
self.instrs.push(LInstruction::LoadAddr { self.instrs.push(LInstruction::LoadAddr {
dest: dest.id, dest: dest.id,
@@ -193,7 +193,7 @@ impl<'a> LFunctionBuilder<'a> {
UInstruction::Call { dest, f, args } => { UInstruction::Call { dest, f, args } => {
self.alloc_stack(dest.id); self.alloc_stack(dest.id);
self.makes_call = true; self.makes_call = true;
let fid = &self.program.fn_map[&f.id]; let fid = &self.program.fn_var.fun(f.id).expect("a");
let sym = self.builder.func(fid); let sym = self.builder.func(fid);
let ret_size = self let ret_size = self
.data .data

View File

@@ -1,15 +1,13 @@
use super::{Type, UInstrInst, UInstruction, UProgram};
use crate::{ use crate::{
common::FileSpan, common::FileSpan,
ir::{Len, Named, ID}, ir::{Len, Named, ID},
}; };
use super::{Type, UInstrInst, UInstruction, UProgram};
use std::{collections::HashMap, fmt::Debug}; use std::{collections::HashMap, fmt::Debug};
pub struct UFunc { pub struct UFunc {
pub args: Vec<VarID>, pub args: Vec<VarID>,
pub ret: Type, pub ret: Type,
pub origin: Origin,
pub instructions: Vec<UInstrInst>, pub instructions: Vec<UInstrInst>,
} }
@@ -22,7 +20,6 @@ pub struct StructField {
pub struct UStruct { pub struct UStruct {
pub fields: HashMap<String, StructField>, pub fields: HashMap<String, StructField>,
pub generics: Vec<GenericID>, pub generics: Vec<GenericID>,
pub origin: Origin,
} }
#[derive(Clone)] #[derive(Clone)]
@@ -32,7 +29,6 @@ pub struct UGeneric {}
pub struct UVar { pub struct UVar {
pub parent: Option<FieldRef>, pub parent: Option<FieldRef>,
pub ty: Type, pub ty: Type,
pub origin: Origin,
} }
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
@@ -50,7 +46,6 @@ pub struct FieldRef {
#[derive(Clone)] #[derive(Clone)]
pub struct UData { pub struct UData {
pub ty: Type, pub ty: Type,
pub origin: Origin,
pub content: Vec<u8>, pub content: Vec<u8>,
} }
@@ -101,7 +96,14 @@ impl<'a> Iterator for InstrIter<'a> {
} }
macro_rules! impl_kind { macro_rules! impl_kind {
// TRUST THIS IS SANE!!! KEEP THE CODE DRY AND SAFE!!!!!!
($struc:ty, $idx:expr, $field:ident, $name:expr) => { ($struc:ty, $idx:expr, $field:ident, $name:expr) => {
impl_kind!($struc, $idx, $field, $name, nofin);
impl Finish for $struc {
fn finish(_: &mut UProgram, _: ID<Self>) {}
}
};
($struc:ty, $idx:expr, $field:ident, $name:expr, nofin) => {
impl Kind for $struc { impl Kind for $struc {
const INDEX: usize = $idx; const INDEX: usize = $idx;
fn from_program_mut(program: &mut UProgram) -> &mut Vec<Option<Self>> { fn from_program_mut(program: &mut UProgram) -> &mut Vec<Option<Self>> {
@@ -117,7 +119,7 @@ macro_rules! impl_kind {
}; };
} }
impl_kind!(UFunc, 0, fns, "func"); impl_kind!(UFunc, 0, fns, "func", nofin);
impl_kind!(UVar, 1, vars, "var"); impl_kind!(UVar, 1, vars, "var");
impl_kind!(UStruct, 2, structs, "struct"); impl_kind!(UStruct, 2, structs, "struct");
impl_kind!(UGeneric, 3, types, "type"); impl_kind!(UGeneric, 3, types, "type");
@@ -130,12 +132,26 @@ pub type StructID = ID<UStruct>;
pub type DataID = ID<UData>; pub type DataID = ID<UData>;
pub type GenericID = ID<UGeneric>; pub type GenericID = ID<UGeneric>;
pub trait Kind { impl Finish for UFunc {
const INDEX: usize; fn finish(p: &mut UProgram, id: ID<Self>) {
fn from_program_mut(program: &mut UProgram) -> &mut Vec<Option<Self>> let var = p.def_searchable(
where p.names.name(id).to_string(),
Self: Sized; Some(UVar {
fn from_program(program: &UProgram) -> &Vec<Option<Self>> parent: None,
where ty: Type::Placeholder,
Self: Sized; }),
p.origins.get(id),
);
p.fn_var.insert(id, var);
}
}
pub trait Kind: Sized {
const INDEX: usize;
fn from_program_mut(program: &mut UProgram) -> &mut Vec<Option<Self>>;
fn from_program(program: &UProgram) -> &Vec<Option<Self>>;
}
pub trait Finish: Sized {
fn finish(program: &mut UProgram, id: ID<Self>);
} }

109
src/ir/upper/maps.rs Normal file
View File

@@ -0,0 +1,109 @@
use super::{FnID, Kind, Origin, VarID, NAMED_KINDS};
use crate::ir::ID;
use std::collections::HashMap;
pub struct OriginMap {
origins: [Vec<Origin>; NAMED_KINDS],
}
impl OriginMap {
pub fn new() -> Self {
Self {
origins: core::array::from_fn(|_| Vec::new()),
}
}
pub fn get<K: Kind>(&self, id: ID<K>) -> Origin {
self.origins[K::INDEX][id.0]
}
pub fn push<K: Kind>(&mut self, origin: Origin) {
self.origins[K::INDEX].push(origin);
}
}
pub struct NameMap {
names: [Vec<String>; NAMED_KINDS],
inv_names: [HashMap<String, usize>; NAMED_KINDS],
}
impl NameMap {
pub fn new() -> Self {
Self {
names: core::array::from_fn(|_| Vec::new()),
inv_names: core::array::from_fn(|_| HashMap::new()),
}
}
pub fn name<K: Kind>(&self, id: ID<K>) -> &str {
&self.names[K::INDEX][id.0]
}
pub fn id<K: Kind>(&self, name: &str) -> Option<ID<K>> {
Some(ID::new(*self.inv_names[K::INDEX].get(name)?))
}
pub fn push<K: Kind>(&mut self, name: String) {
self.inv_names[K::INDEX].insert(name.clone(), self.names[K::INDEX].len());
self.names[K::INDEX].push(name);
}
}
pub struct FnVarMap {
vtf: HashMap<VarID, FnID>,
ftv: Vec<VarID>,
}
impl FnVarMap {
pub fn new() -> Self {
Self {
vtf: HashMap::new(),
ftv: Vec::new(),
}
}
pub fn insert(&mut self, f: FnID, v: VarID) {
self.vtf.insert(v, f);
self.ftv.push(v);
}
pub fn var(&self, f: FnID) -> VarID {
self.ftv[f.0]
}
pub fn fun(&self, v: VarID) -> Option<FnID> {
self.vtf.get(&v).copied()
}
}
#[derive(Debug, Clone, Copy)]
pub struct Ident {
id: usize,
kind: usize,
}
impl<K: Kind> From<ID<K>> for Ident {
fn from(id: ID<K>) -> Self {
Self {
id: id.0,
kind: K::INDEX,
}
}
}
// this isn't really a map... but also keeps track of "side data"
#[derive(Debug, Clone, Copy)]
pub struct Idents {
pub latest: Ident,
pub kinds: [Option<usize>; NAMED_KINDS],
}
impl Idents {
pub fn new(latest: Ident) -> Self {
let mut s = Self {
latest,
kinds: [None; NAMED_KINDS],
};
s.insert(latest);
s
}
pub fn insert(&mut self, i: Ident) {
self.latest = i;
self.kinds[i.kind] = Some(i.id);
}
pub fn get<K: Kind>(&self) -> Option<ID<K>> {
self.kinds[K::INDEX].map(|i| i.into())
}
}

View File

@@ -5,8 +5,11 @@ mod program;
mod validate; mod validate;
mod error; mod error;
mod inst; mod inst;
mod maps;
use super::*; use super::*;
use maps::*;
pub use maps::Idents;
pub use kind::*; pub use kind::*;
pub use instr::*; pub use instr::*;
pub use ty::*; pub use ty::*;

View File

@@ -1,6 +1,5 @@
use std::{collections::HashMap, fmt::Debug}; use super::*;
use std::collections::HashMap;
use super::{inst::VarInst, *};
pub struct UProgram { pub struct UProgram {
pub fns: Vec<Option<UFunc>>, pub fns: Vec<Option<UFunc>>,
@@ -8,39 +7,14 @@ pub struct UProgram {
pub structs: Vec<Option<UStruct>>, pub structs: Vec<Option<UStruct>>,
pub types: Vec<Option<UGeneric>>, pub types: Vec<Option<UGeneric>>,
pub data: Vec<Option<UData>>, pub data: Vec<Option<UData>>,
pub start: Option<FnID>,
pub names: NameMap, pub names: NameMap,
pub origins: OriginMap,
// todo: these feel weird raw // todo: these feel weird raw
pub fn_map: HashMap<VarID, FnID>, pub fn_var: FnVarMap,
pub inv_fn_map: Vec<VarID>,
pub temp: usize, pub temp: usize,
pub name_stack: Vec<HashMap<String, Idents>>, pub name_stack: Vec<HashMap<String, Idents>>,
} }
pub struct NameMap {
names: [Vec<String>; NAMED_KINDS],
inv_names: [HashMap<String, usize>; NAMED_KINDS],
}
impl NameMap {
pub fn new() -> Self {
Self {
names: core::array::from_fn(|_| Vec::new()),
inv_names: core::array::from_fn(|_| HashMap::new()),
}
}
pub fn get<K: Kind>(&self, id: ID<K>) -> &str {
&self.names[K::INDEX][id.0]
}
pub fn lookup<K: Kind>(&self, name: &str) -> Option<ID<K>> {
Some(ID::new(*self.inv_names[K::INDEX].get(name)?))
}
pub fn push<K: Kind>(&mut self, name: String) {
self.inv_names[K::INDEX].insert(name.clone(), self.names[K::INDEX].len());
self.names[K::INDEX].push(name);
}
}
impl UProgram { impl UProgram {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
@@ -49,10 +23,9 @@ impl UProgram {
structs: Vec::new(), structs: Vec::new(),
types: Vec::new(), types: Vec::new(),
data: Vec::new(), data: Vec::new(),
start: None,
names: NameMap::new(), names: NameMap::new(),
fn_map: HashMap::new(), origins: OriginMap::new(),
inv_fn_map: Vec::new(), fn_var: FnVarMap::new(),
temp: 0, temp: 0,
name_stack: vec![HashMap::new()], name_stack: vec![HashMap::new()],
} }
@@ -87,7 +60,7 @@ impl UProgram {
.unwrap_or_else(|| panic!("{id:?} not defined yet!")) .unwrap_or_else(|| panic!("{id:?} not defined yet!"))
} }
pub fn get_fn_var(&self, id: VarID) -> Option<&UFunc> { pub fn get_fn_var(&self, id: VarID) -> Option<&UFunc> {
self.fns[self.fn_map.get(&id)?.0].as_ref() self.fns[self.fn_var.fun(id)?.0].as_ref()
} }
pub fn temp_subvar(&mut self, origin: Origin, ty: Type, parent: FieldRef) -> VarInst { pub fn temp_subvar(&mut self, origin: Origin, ty: Type, parent: FieldRef) -> VarInst {
self.temp_var_inner(origin, ty, Some(parent)) self.temp_var_inner(origin, ty, Some(parent))
@@ -99,7 +72,8 @@ impl UProgram {
fn temp_var_inner(&mut self, origin: Origin, ty: Type, parent: Option<FieldRef>) -> VarInst { fn temp_var_inner(&mut self, origin: Origin, ty: Type, parent: Option<FieldRef>) -> VarInst {
let v = self.def( let v = self.def(
format!("temp{}", self.temp), format!("temp{}", self.temp),
Some(UVar { parent, origin, ty }), Some(UVar { parent, ty }),
origin,
); );
self.temp += 1; self.temp += 1;
VarInst { VarInst {
@@ -112,16 +86,23 @@ impl UProgram {
K::from_program_mut(self)[id.0] = Some(k); K::from_program_mut(self)[id.0] = Some(k);
} }
pub fn def<K: Kind>(&mut self, name: String, k: Option<K>) -> ID<K> { pub fn def<K: Kind + Finish>(&mut self, name: String, k: Option<K>, origin: Origin) -> ID<K> {
self.names.push::<K>(name); self.names.push::<K>(name);
self.origins.push::<K>(origin);
let vec = K::from_program_mut(self); let vec = K::from_program_mut(self);
let id = ID::new(vec.len()); let id = ID::new(vec.len());
vec.push(k); vec.push(k);
K::finish(self, id);
id id
} }
pub fn def_searchable<K: Kind>(&mut self, name: String, k: Option<K>) -> ID<K> { pub fn def_searchable<K: Kind + Finish>(
let id = self.def(name.clone(), k); &mut self,
name: String,
k: Option<K>,
origin: Origin,
) -> ID<K> {
let id = self.def(name.clone(), k, origin);
self.name_on_stack(id, name); self.name_on_stack(id, name);
id id
} }
@@ -135,7 +116,7 @@ impl UProgram {
if let Type::Generic { id } = field.ty { if let Type::Generic { id } = field.ty {
for (i, g) in struc.generics.iter().enumerate() { for (i, g) in struc.generics.iter().enumerate() {
if *g == id { if *g == id {
return Some(&args[i]) return Some(&args[i]);
} }
} }
} }
@@ -146,7 +127,7 @@ impl UProgram {
let mut str = String::new(); let mut str = String::new();
match ty { match ty {
Type::Struct { id: base, args } => { Type::Struct { id: base, args } => {
str += self.names.get(*base); str += self.names.name(*base);
if let Some(arg) = args.first() { if let Some(arg) = args.first() {
str = str + "<" + &self.type_name(arg); str = str + "<" + &self.type_name(arg);
} }
@@ -173,7 +154,7 @@ impl UProgram {
} }
Type::Error => str += "{error}", Type::Error => str += "{error}",
Type::Infer => str += "{inferred}", Type::Infer => str += "{inferred}",
Type::Generic { id } => str += self.names.get(*id), Type::Generic { id } => str += self.names.name(*id),
Type::Bits(size) => str += &format!("b{}", size), Type::Bits(size) => str += &format!("b{}", size),
Type::Array(t, len) => str += &format!("[{}; {len}]", self.type_name(t)), Type::Array(t, len) => str += &format!("[{}; {len}]", self.type_name(t)),
Type::Unit => str += "()", Type::Unit => str += "()",
@@ -206,42 +187,3 @@ impl UProgram {
.map(|(i, x)| (ID::new(i), x)) .map(|(i, x)| (ID::new(i), x))
} }
} }
#[derive(Debug, Clone, Copy)]
pub struct Ident {
id: usize,
kind: usize,
}
impl<K: Kind> From<ID<K>> for Ident {
fn from(id: ID<K>) -> Self {
Self {
id: id.0,
kind: K::INDEX,
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct Idents {
pub latest: Ident,
pub kinds: [Option<usize>; NAMED_KINDS],
}
impl Idents {
fn new(latest: Ident) -> Self {
let mut s = Self {
latest,
kinds: [None; NAMED_KINDS],
};
s.insert(latest);
s
}
fn insert(&mut self, i: Ident) {
self.latest = i;
self.kinds[i.kind] = Some(i.id);
}
pub fn get<K: Kind>(&self) -> Option<ID<K>> {
self.kinds[K::INDEX].map(|i| i.into())
}
}

View File

@@ -5,36 +5,43 @@ use crate::common::{CompilerMsg, CompilerOutput, FileSpan};
impl UProgram { impl UProgram {
pub fn validate(&self) -> CompilerOutput { pub fn validate(&self) -> CompilerOutput {
let mut output = CompilerOutput::new(); let mut output = CompilerOutput::new();
for f in self.fns.iter().flatten() { for (id, f) in self.iter_fns() {
self.validate_fn(&f.instructions, f.origin, &f.ret, &mut output, true, false); self.validate_fn(
&f.instructions,
self.origins.get(id),
&f.ret,
&mut output,
true,
false,
);
} }
for (id, var) in self.iter_vars() { for (id, var) in self.iter_vars() {
if var.ty == Type::Error { if var.ty == Type::Error {
output.err(CompilerMsg { output.err(CompilerMsg {
msg: format!("Var {:?} is error type!", id), msg: format!("Var {:?} is error type!", id),
spans: vec![var.origin], spans: vec![self.origins.get(id)],
}); });
} }
if var.ty == Type::Infer { if var.ty == Type::Infer {
output.err(CompilerMsg { output.err(CompilerMsg {
msg: format!("Var {:?} cannot be inferred", id), msg: format!("Var {:?} cannot be inferred", id),
spans: vec![var.origin], spans: vec![self.origins.get(id)],
}); });
} }
if var.ty == Type::Placeholder { if var.ty == Type::Placeholder {
output.err(CompilerMsg { output.err(CompilerMsg {
msg: format!("Var {:?} still placeholder!", id), msg: format!("Var {:?} still placeholder!", id),
spans: vec![var.origin], spans: vec![self.origins.get(id)],
}); });
} }
if let Some(parent) = &var.parent { if let Some(parent) = &var.parent {
let pty = &self.get(parent.var).unwrap().ty; let pty = &self.get(parent.var).unwrap().ty;
if let Some(ft) = self.field_type(pty, &parent.field) { if let Some(ft) = self.field_type(pty, &parent.field) {
output.check_assign(self, &var.ty, ft, var.origin); output.check_assign(self, &var.ty, ft, self.origins.get(id));
} else { } else {
output.err(CompilerMsg { output.err(CompilerMsg {
msg: format!("invalid parent!"), msg: format!("invalid parent!"),
spans: vec![var.origin], spans: vec![self.origins.get(id)],
}); });
} }
} }

View File

@@ -15,14 +15,7 @@ impl Node<PVarDef> {
None => Type::Infer, None => Type::Infer,
}; };
Some(VarInst { Some(VarInst {
id: program.def_searchable( id: program.def_searchable(name, Some(UVar { ty, parent: None }), self.span),
name,
Some(UVar {
ty,
parent: None,
origin: self.span,
}),
),
span: self.span, span: self.span,
}) })
} }

View File

@@ -16,9 +16,9 @@ impl FnLowerable for PExpr {
format!("string \"{}\"", s.replace("\n", "\\n")), format!("string \"{}\"", s.replace("\n", "\\n")),
Some(UData { Some(UData {
ty: Type::Bits(8).arr(data.len() as u32), ty: Type::Bits(8).arr(data.len() as u32),
origin: l.span,
content: data, content: data,
}), }),
l.span,
); );
ctx.push(UInstruction::LoadSlice { dest, src }); ctx.push(UInstruction::LoadSlice { dest, src });
dest dest
@@ -30,9 +30,9 @@ impl FnLowerable for PExpr {
format!("char '{c}'"), format!("char '{c}'"),
Some(UData { Some(UData {
ty, ty,
origin: l.span,
content: c.to_string().as_bytes().to_vec(), content: c.to_string().as_bytes().to_vec(),
}), }),
l.span,
); );
ctx.push(UInstruction::LoadData { dest, src }); ctx.push(UInstruction::LoadData { dest, src });
dest dest
@@ -45,9 +45,9 @@ impl FnLowerable for PExpr {
format!("num {n:?}"), format!("num {n:?}"),
Some(UData { Some(UData {
ty, ty,
origin: l.span,
content: n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(), content: n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(),
}), }),
l.span
); );
ctx.push(UInstruction::LoadData { dest, src }); ctx.push(UInstruction::LoadData { dest, src });
dest dest

View File

@@ -1,9 +1,6 @@
use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction}; use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction};
use crate::{ use crate::{
ir::{ ir::{FieldRef, FnID, Idents, Type, UFunc, UInstrInst, UInstruction, UProgram, UVar, VarInst},
FieldRef, FnID, Idents, InstrIter, Type, UFunc, UInstrInst, UInstruction, UProgram, UVar,
VarInst,
},
parser, parser,
}; };
@@ -22,17 +19,7 @@ impl PFunction {
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> { pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
let header = self.header.as_ref()?; let header = self.header.as_ref()?;
let name = header.name.as_ref()?; let name = header.name.as_ref()?;
let id = p.def_searchable(name.to_string(), None); let id = p.def_searchable(name.to_string(), None, self.header.span);
let var = p.def_searchable(
name.to_string(),
Some(UVar {
parent: None,
ty: Type::Placeholder,
origin: self.header.span,
}),
);
p.fn_map.insert(var, id);
p.inv_fn_map.push(var);
Some(id) Some(id)
} }
pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) { pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) {
@@ -63,15 +50,13 @@ impl PFunction {
span: src.span, span: src.span,
}); });
} }
let origin = self.header.span;
let instructions = ctx.instructions; let instructions = ctx.instructions;
let f = UFunc { let f = UFunc {
origin,
args, args,
ret, ret,
instructions, instructions,
}; };
p.expect_mut(p.inv_fn_map[id.0]).ty = f.ty(p); p.expect_mut(p.fn_var.var(id)).ty = f.ty(p);
p.write(id, f) p.write(id, f)
} }
} }

View File

@@ -49,7 +49,7 @@ impl PStruct {
let generics = self let generics = self
.generics .generics
.iter() .iter()
.flat_map(|a| a.as_ref()?.lower(p)) .flat_map(|a| a.lower(p))
.collect(); .collect();
let fields = match &self.fields { let fields = match &self.fields {
PStructFields::Named(nodes) => nodes PStructFields::Named(nodes) => nodes
@@ -75,14 +75,7 @@ impl PStruct {
.into_iter() .into_iter()
.map(|(name, ty)| (name, StructField { ty })) .map(|(name, ty)| (name, StructField { ty }))
.collect(); .collect();
p.write( p.write(id, UStruct { generics, fields });
id,
UStruct {
origin: span,
generics,
fields,
},
);
p.pop(); p.pop();
Some(()) Some(())
} }
@@ -90,8 +83,9 @@ impl PStruct {
impl Node<PStruct> { impl Node<PStruct> {
pub fn lower_name(&self, p: &mut UProgram) -> Option<StructID> { pub fn lower_name(&self, p: &mut UProgram) -> Option<StructID> {
let name = self.as_ref()?.name.as_ref()?.to_string(); let s = self.as_ref()?;
let id = p.def_searchable(name.to_string(), None); let name = s.name.as_ref()?.to_string();
let id = p.def_searchable(name.to_string(), None, s.name.span);
Some(id) Some(id)
} }
pub fn lower(&self, id: StructID, p: &mut UProgram, output: &mut CompilerOutput) { pub fn lower(&self, id: StructID, p: &mut UProgram, output: &mut CompilerOutput) {

View File

@@ -43,11 +43,10 @@ impl PType {
} }
} }
impl PGenericDef { impl Node<PGenericDef> {
pub fn lower(&self, p: &mut UProgram) -> Option<GenericID> { pub fn lower(&self, p: &mut UProgram) -> Option<GenericID> {
let Some(name) = self.name.as_ref() else { let s = self.as_ref()?;
return None; let name = s.name.as_ref()?;
}; Some(p.def_searchable(name.to_string(), Some(UGeneric {}), self.span))
Some(p.def_searchable(name.to_string(), Some(UGeneric {})))
} }
} }