huge refactor, can now define structs out of order
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
compiler::arch::riscv::Reg,
|
||||
ir::{
|
||||
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, IRUInstruction, Type, VarInst,
|
||||
arch::riscv64::RV64Instruction, AsmBlockArg, AsmBlockArgType, UInstruction, Type, VarInst,
|
||||
},
|
||||
parser::PAsmBlockArg,
|
||||
};
|
||||
@@ -48,7 +48,7 @@ impl FnLowerable for PAsmBlock {
|
||||
}
|
||||
}
|
||||
}
|
||||
let block = IRUInstruction::AsmBlock {
|
||||
let block = UInstruction::AsmBlock {
|
||||
instructions: {
|
||||
let mut v = Vec::new();
|
||||
for i in &self.instructions {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::ir::{IRUInstruction, Type, VarInst};
|
||||
use crate::ir::{Type, UInstruction, VarInst};
|
||||
|
||||
use super::{FnLowerCtx, FnLowerable, PBlock, PStatement};
|
||||
|
||||
@@ -23,17 +23,20 @@ impl FnLowerable for PStatement {
|
||||
let def = def.lower(ctx.program, ctx.output)?;
|
||||
let res = e.lower(ctx);
|
||||
if let Some(res) = res {
|
||||
ctx.program.name_var(&def, res.id);
|
||||
ctx.push(UInstruction::Mv {
|
||||
dest: def,
|
||||
src: res,
|
||||
});
|
||||
}
|
||||
None
|
||||
}
|
||||
super::PStatement::Return(e) => {
|
||||
if let Some(e) = e {
|
||||
let src = e.lower(ctx)?;
|
||||
ctx.push_at(IRUInstruction::Ret { src }, src.span);
|
||||
ctx.push_at(UInstruction::Ret { src }, src.span);
|
||||
} else {
|
||||
let src = ctx.temp(Type::Unit);
|
||||
ctx.push_at(IRUInstruction::Ret { src }, src.span);
|
||||
ctx.push_at(UInstruction::Ret { src }, src.span);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -1,26 +1,35 @@
|
||||
use crate::ir::{IRUProgram, Origin, Type, VarDef};
|
||||
use crate::ir::{Type, UProgram, UStruct, UVar, VarInst};
|
||||
|
||||
use super::{CompilerMsg, CompilerOutput, FileSpan, Node, PType, PVarDef};
|
||||
|
||||
impl Node<PVarDef> {
|
||||
pub fn lower(&self, program: &mut IRUProgram, output: &mut CompilerOutput) -> Option<VarDef> {
|
||||
pub fn lower(&self, program: &mut UProgram, output: &mut CompilerOutput) -> Option<VarInst> {
|
||||
let s = self.as_ref()?;
|
||||
let name = s.name.as_ref()?.to_string();
|
||||
let name = s
|
||||
.name
|
||||
.as_ref()
|
||||
.map(|n| n.to_string())
|
||||
.unwrap_or("{error}".to_string());
|
||||
let ty = match &s.ty {
|
||||
Some(ty) => ty.lower(program, output),
|
||||
None => Type::Infer,
|
||||
};
|
||||
Some(VarDef {
|
||||
name,
|
||||
ty,
|
||||
parent: None,
|
||||
origin: self.span,
|
||||
Some(VarInst {
|
||||
id: program.def_searchable(
|
||||
name,
|
||||
Some(UVar {
|
||||
ty,
|
||||
parent: None,
|
||||
origin: self.span,
|
||||
}),
|
||||
),
|
||||
span: self.span,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Node<PType> {
|
||||
pub fn lower(&self, namespace: &mut IRUProgram, output: &mut CompilerOutput) -> Type {
|
||||
pub fn lower(&self, namespace: &mut UProgram, output: &mut CompilerOutput) -> Type {
|
||||
self.as_ref()
|
||||
.map(|t| t.lower(namespace, output, self.span))
|
||||
.unwrap_or(Type::Error)
|
||||
@@ -30,14 +39,17 @@ impl Node<PType> {
|
||||
impl PType {
|
||||
pub fn lower(
|
||||
&self,
|
||||
namespace: &mut IRUProgram,
|
||||
namespace: &mut UProgram,
|
||||
output: &mut CompilerOutput,
|
||||
span: FileSpan,
|
||||
) -> Type {
|
||||
let Some(name) = self.name.as_ref() else {
|
||||
return Type::Error;
|
||||
};
|
||||
match namespace.get(&name).and_then(|ids| ids.struc) {
|
||||
match namespace
|
||||
.get_idents(name)
|
||||
.and_then(|ids| ids.get::<UStruct>())
|
||||
{
|
||||
Some(id) => {
|
||||
let args = self
|
||||
.args
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::{func::FnLowerCtx, FnLowerable, PExpr, UnaryOp};
|
||||
use crate::{
|
||||
ir::{DataDef, FieldRef, IRUInstruction, Type, VarInst},
|
||||
ir::{FieldRef, Type, UData, UInstruction, VarInst},
|
||||
parser::PInfixOp,
|
||||
};
|
||||
|
||||
@@ -12,55 +12,53 @@ impl FnLowerable for PExpr {
|
||||
super::PLiteral::String(s) => {
|
||||
let dest = ctx.program.temp_var(l.span, Type::Bits(8).slice());
|
||||
let data = s.as_bytes().to_vec();
|
||||
let src = ctx.program.def_data(
|
||||
DataDef {
|
||||
let src = ctx.program.def(
|
||||
format!("string \"{}\"", s.replace("\n", "\\n")),
|
||||
Some(UData {
|
||||
ty: Type::Bits(8).arr(data.len() as u32),
|
||||
origin: l.span,
|
||||
label: format!("string \"{}\"", s.replace("\n", "\\n")),
|
||||
},
|
||||
data,
|
||||
content: data,
|
||||
}),
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadSlice { dest, src });
|
||||
ctx.push(UInstruction::LoadSlice { dest, src });
|
||||
dest
|
||||
}
|
||||
super::PLiteral::Char(c) => {
|
||||
let ty = Type::Bits(8);
|
||||
let dest = ctx.program.temp_var(l.span, ty.clone());
|
||||
let src = ctx.program.def_data(
|
||||
DataDef {
|
||||
let src = ctx.program.def(
|
||||
format!("char '{c}'"),
|
||||
Some(UData {
|
||||
ty,
|
||||
origin: l.span,
|
||||
label: format!("char '{c}'"),
|
||||
},
|
||||
c.to_string().as_bytes().to_vec(),
|
||||
content: c.to_string().as_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadData { dest, src });
|
||||
ctx.push(UInstruction::LoadData { dest, src });
|
||||
dest
|
||||
}
|
||||
super::PLiteral::Number(n) => {
|
||||
// TODO: temp
|
||||
let ty = Type::Bits(64);
|
||||
let dest = ctx.program.temp_var(l.span, Type::Bits(64));
|
||||
let src = ctx.program.def_data(
|
||||
DataDef {
|
||||
let src = ctx.program.def(
|
||||
format!("num {n:?}"),
|
||||
Some(UData {
|
||||
ty,
|
||||
origin: l.span,
|
||||
label: format!("num {n:?}"),
|
||||
},
|
||||
n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(),
|
||||
content: n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(),
|
||||
}),
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadData { dest, src });
|
||||
ctx.push(UInstruction::LoadData { dest, src });
|
||||
dest
|
||||
}
|
||||
super::PLiteral::Unit => {
|
||||
todo!();
|
||||
}
|
||||
super::PLiteral::Unit => ctx.program.temp_var(l.span, Type::Unit),
|
||||
},
|
||||
PExpr::Ident(i) => ctx.get_var(i)?,
|
||||
PExpr::BinaryOp(op, e1, e2) => {
|
||||
let res1 = e1.lower(ctx)?;
|
||||
if *op == PInfixOp::Access {
|
||||
let sty = &ctx.program.get_var(res1.id).ty;
|
||||
let sty = &ctx.program.expect(res1.id).ty;
|
||||
let Type::Struct {
|
||||
id: struct_id,
|
||||
args,
|
||||
@@ -72,7 +70,7 @@ impl FnLowerable for PExpr {
|
||||
));
|
||||
return None;
|
||||
};
|
||||
let struc = ctx.program.get_struct(*struct_id);
|
||||
let struc = ctx.program.expect(*struct_id);
|
||||
let Some(box PExpr::Ident(ident)) = &e2.inner else {
|
||||
ctx.err("Field accesses must be identifiers".to_string());
|
||||
return None;
|
||||
@@ -102,7 +100,7 @@ impl FnLowerable for PExpr {
|
||||
PInfixOp::GreaterThan => todo!(),
|
||||
PInfixOp::Access => todo!(),
|
||||
PInfixOp::Assign => {
|
||||
ctx.push(IRUInstruction::Mv {
|
||||
ctx.push(UInstruction::Mv {
|
||||
dest: res1,
|
||||
src: res2,
|
||||
});
|
||||
@@ -115,15 +113,15 @@ impl FnLowerable for PExpr {
|
||||
let res = e.lower(ctx)?;
|
||||
match op {
|
||||
UnaryOp::Ref => {
|
||||
let temp = ctx.temp(ctx.program.get_var(res.id).ty.clone().rf());
|
||||
ctx.push(IRUInstruction::Ref {
|
||||
let temp = ctx.temp(ctx.program.expect(res.id).ty.clone().rf());
|
||||
ctx.push(UInstruction::Ref {
|
||||
dest: temp,
|
||||
src: res,
|
||||
});
|
||||
temp
|
||||
}
|
||||
UnaryOp::Deref => {
|
||||
let t = &ctx.program.get_var(res.id).ty;
|
||||
let t = &ctx.program.expect(res.id).ty;
|
||||
let Type::Ref(inner) = t else {
|
||||
ctx.err(format!(
|
||||
"Cannot dereference type {:?}",
|
||||
@@ -145,22 +143,13 @@ impl FnLowerable for PExpr {
|
||||
let arg = arg.lower(ctx)?;
|
||||
nargs.push(arg);
|
||||
}
|
||||
let def = ctx.program.get_fn_var(fe.id);
|
||||
let ty = match def {
|
||||
Some(def) => def.ret.clone(),
|
||||
None => {
|
||||
ctx.err_at(
|
||||
e.span,
|
||||
format!(
|
||||
"Expected function, found {}",
|
||||
ctx.program.type_name(&ctx.program.get_var(fe.id).ty)
|
||||
),
|
||||
);
|
||||
Type::Error
|
||||
}
|
||||
};
|
||||
let ty = ctx
|
||||
.program
|
||||
.get_fn_var(fe.id)
|
||||
.map(|f| f.ret.clone())
|
||||
.unwrap_or(Type::Error);
|
||||
let temp = ctx.temp(ty);
|
||||
ctx.push(IRUInstruction::Call {
|
||||
ctx.push(UInstruction::Call {
|
||||
dest: temp,
|
||||
f: fe,
|
||||
args: nargs,
|
||||
@@ -176,7 +165,7 @@ impl FnLowerable for PExpr {
|
||||
body.lower(&mut body_ctx);
|
||||
let body = body_ctx.instructions;
|
||||
ctx.program.pop();
|
||||
ctx.push(IRUInstruction::If { cond, body });
|
||||
ctx.push(UInstruction::If { cond, body });
|
||||
return None;
|
||||
}
|
||||
PExpr::Loop(body) => {
|
||||
@@ -185,15 +174,15 @@ impl FnLowerable for PExpr {
|
||||
body.lower(&mut body_ctx);
|
||||
let body = body_ctx.instructions;
|
||||
ctx.program.pop();
|
||||
ctx.push(IRUInstruction::Loop { body });
|
||||
ctx.push(UInstruction::Loop { body });
|
||||
return None;
|
||||
}
|
||||
PExpr::Break => {
|
||||
ctx.push(IRUInstruction::Break);
|
||||
ctx.push(UInstruction::Break);
|
||||
return None;
|
||||
}
|
||||
PExpr::Continue => {
|
||||
ctx.push(IRUInstruction::Continue);
|
||||
ctx.push(UInstruction::Continue);
|
||||
return None;
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,110 +1,102 @@
|
||||
use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction};
|
||||
use crate::{
|
||||
ir::{
|
||||
FnDef, FnID, IRUFunction, IRUInstrInst, IRUInstruction, IRUProgram, Idents, Type, VarDef,
|
||||
VarInst, FieldRef,
|
||||
},
|
||||
ir::{FieldRef, FnID, Idents, Type, UFunc, UInstrInst, UInstruction, UProgram, UVar, VarInst},
|
||||
parser,
|
||||
};
|
||||
|
||||
impl Node<PFunction> {
|
||||
pub fn lower_header(&self, map: &mut IRUProgram, output: &mut CompilerOutput) -> Option<FnID> {
|
||||
self.as_ref()?.lower_header(map, output)
|
||||
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
|
||||
Some(self.as_ref()?.lower_name(p)?)
|
||||
}
|
||||
pub fn lower_body(
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut IRUProgram,
|
||||
output: &mut CompilerOutput,
|
||||
) -> Option<IRUFunction> {
|
||||
Some(self.as_ref()?.lower_body(id, map, output))
|
||||
pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) {
|
||||
if let Some(s) = self.as_ref() {
|
||||
s.lower(id, p, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PFunction {
|
||||
pub fn lower_header(&self, map: &mut IRUProgram, output: &mut CompilerOutput) -> Option<FnID> {
|
||||
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
|
||||
let header = self.header.as_ref()?;
|
||||
let name = header.name.as_ref()?;
|
||||
let args = header
|
||||
.args
|
||||
.iter()
|
||||
.map(|a| {
|
||||
a.lower(map, output).unwrap_or(VarDef {
|
||||
name: "{error}".to_string(),
|
||||
origin: a.span,
|
||||
parent: None,
|
||||
ty: Type::Error,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
let ret = match &header.ret {
|
||||
Some(ty) => ty.lower(map, output),
|
||||
None => Type::Unit,
|
||||
};
|
||||
Some(map.def_fn(FnDef {
|
||||
name: name.to_string(),
|
||||
origin: self.header.span,
|
||||
args,
|
||||
ret,
|
||||
}))
|
||||
let id = p.def_searchable(name.to_string(), None);
|
||||
let var = p.def_searchable(
|
||||
name.to_string(),
|
||||
Some(UVar {
|
||||
parent: None,
|
||||
ty: Type::Error,
|
||||
origin: self.header.span,
|
||||
}),
|
||||
);
|
||||
p.fn_map.insert(var, id);
|
||||
p.inv_fn_map.push(var);
|
||||
Some(id)
|
||||
}
|
||||
pub fn lower_body(
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut IRUProgram,
|
||||
output: &mut CompilerOutput,
|
||||
) -> IRUFunction {
|
||||
let def = map.get_fn(id).clone();
|
||||
let args = def.args.iter().map(|a| map.named_var(a.clone())).collect();
|
||||
pub fn lower(&self, id: FnID, p: &mut UProgram, output: &mut CompilerOutput) {
|
||||
let (args, ret) = if let Some(header) = self.header.as_ref() {
|
||||
(
|
||||
header
|
||||
.args
|
||||
.iter()
|
||||
.flat_map(|a| Some(a.lower(p, output)?.id))
|
||||
.collect(),
|
||||
match &header.ret {
|
||||
Some(ty) => ty.lower(p, output),
|
||||
None => Type::Unit,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
(Vec::new(), Type::Error)
|
||||
};
|
||||
let mut ctx = FnLowerCtx {
|
||||
instructions: Vec::new(),
|
||||
program: map,
|
||||
program: p,
|
||||
output,
|
||||
span: self.body.span,
|
||||
};
|
||||
if let Some(src) = self.body.lower(&mut ctx) {
|
||||
ctx.instructions.push(IRUInstrInst {
|
||||
i: IRUInstruction::Ret { src },
|
||||
ctx.instructions.push(UInstrInst {
|
||||
i: UInstruction::Ret { src },
|
||||
span: src.span,
|
||||
});
|
||||
}
|
||||
IRUFunction {
|
||||
name: def.name.clone(),
|
||||
let origin = self.header.span;
|
||||
let f = UFunc {
|
||||
origin,
|
||||
args,
|
||||
ret: def.ret,
|
||||
ret,
|
||||
instructions: ctx.instructions,
|
||||
}
|
||||
};
|
||||
p.expect_mut(p.inv_fn_map[id.0]).ty = f.ty(p);
|
||||
p.write(id, f)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FnLowerCtx<'a> {
|
||||
pub program: &'a mut IRUProgram,
|
||||
pub instructions: Vec<IRUInstrInst>,
|
||||
pub program: &'a mut UProgram,
|
||||
pub instructions: Vec<UInstrInst>,
|
||||
pub output: &'a mut CompilerOutput,
|
||||
pub span: FileSpan,
|
||||
}
|
||||
|
||||
impl FnLowerCtx<'_> {
|
||||
pub fn get(&mut self, node: &Node<parser::PIdent>) -> Option<Idents> {
|
||||
pub fn get_idents(&mut self, node: &Node<parser::PIdent>) -> Option<Idents> {
|
||||
let name = node.inner.as_ref()?;
|
||||
let res = self.program.get(name);
|
||||
let res = self.program.get_idents(name);
|
||||
if res.is_none() {
|
||||
self.err_at(node.span, format!("Identifier '{}' not found", name));
|
||||
}
|
||||
res
|
||||
}
|
||||
pub fn get_var(&mut self, node: &Node<parser::PIdent>) -> Option<VarInst> {
|
||||
let ids = self.get(node)?;
|
||||
if ids.var.is_none() {
|
||||
let ids = self.get_idents(node)?;
|
||||
if ids.get::<UVar>().is_none() {
|
||||
self.err_at(
|
||||
node.span,
|
||||
format!(
|
||||
"Variable '{}' not found; Type found but cannot be used here",
|
||||
node.inner.as_ref()?
|
||||
),
|
||||
format!("Variable '{}' not found", node.inner.as_ref()?),
|
||||
);
|
||||
}
|
||||
ids.var.map(|id| VarInst {
|
||||
ids.get::<UVar>().map(|id| VarInst {
|
||||
id,
|
||||
span: node.span,
|
||||
})
|
||||
@@ -121,11 +113,11 @@ impl FnLowerCtx<'_> {
|
||||
pub fn temp_subvar(&mut self, ty: Type, parent: FieldRef) -> VarInst {
|
||||
self.program.temp_subvar(self.span, ty, parent)
|
||||
}
|
||||
pub fn push(&mut self, i: IRUInstruction) {
|
||||
self.instructions.push(IRUInstrInst { i, span: self.span });
|
||||
pub fn push(&mut self, i: UInstruction) {
|
||||
self.instructions.push(UInstrInst { i, span: self.span });
|
||||
}
|
||||
pub fn push_at(&mut self, i: IRUInstruction, span: FileSpan) {
|
||||
self.instructions.push(IRUInstrInst { i, span });
|
||||
pub fn push_at(&mut self, i: UInstruction, span: FileSpan) {
|
||||
self.instructions.push(UInstrInst { i, span });
|
||||
}
|
||||
pub fn branch<'a>(&'a mut self) -> FnLowerCtx<'a> {
|
||||
FnLowerCtx {
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
use crate::ir::IRUProgram;
|
||||
use crate::ir::UProgram;
|
||||
|
||||
use super::{PModule, CompilerOutput};
|
||||
use super::{CompilerOutput, PModule};
|
||||
|
||||
impl PModule {
|
||||
pub fn lower(&self, p: &mut IRUProgram, output: &mut CompilerOutput) {
|
||||
pub fn lower(&self, p: &mut UProgram, output: &mut CompilerOutput) {
|
||||
let mut structs = Vec::new();
|
||||
for s in &self.structs {
|
||||
s.lower(p, output);
|
||||
structs.push(s.lower_name(p));
|
||||
}
|
||||
for (s, id) in self.structs.iter().zip(structs) {
|
||||
if let Some(id) = id {
|
||||
s.lower(id, p, output);
|
||||
}
|
||||
}
|
||||
let mut fns = Vec::new();
|
||||
for f in &self.functions {
|
||||
if let Some(id) = f.lower_header(p, output) {
|
||||
fns.push(Some(id));
|
||||
} else {
|
||||
fns.push(None)
|
||||
}
|
||||
fns.push(f.lower_name(p));
|
||||
}
|
||||
for (f, id) in self.functions.iter().zip(fns) {
|
||||
if let Some(id) = id {
|
||||
if let Some(res) = f.lower_body(id, p, output) {
|
||||
p.write_fn(id, res);
|
||||
}
|
||||
f.lower(id, p, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::collections::HashMap;
|
||||
|
||||
use crate::{
|
||||
common::{CompilerOutput, FileSpan},
|
||||
ir::{FieldID, IRUInstruction, IRUProgram, StructDef, StructField, Type, VarInst},
|
||||
ir::{FieldID, StructField, StructID, Type, UInstruction, UProgram, UStruct, VarInst},
|
||||
parser::{Node, PConstruct, PConstructFields, PStruct, PStructFields},
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ impl FnLowerable for PConstruct {
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
|
||||
let ty = self.name.lower(ctx.program, ctx.output);
|
||||
let field_map = match ty {
|
||||
Type::Struct { id, .. } => ctx.program.get_struct(id),
|
||||
Type::Struct { id, .. } => ctx.program.expect(id),
|
||||
_ => {
|
||||
ctx.err(format!(
|
||||
"Type {} cannot be constructed",
|
||||
@@ -62,7 +62,7 @@ impl FnLowerable for PConstruct {
|
||||
PConstructFields::None => Default::default(),
|
||||
};
|
||||
let id = ctx.temp(ty);
|
||||
ctx.push(IRUInstruction::Construct { dest: id, fields });
|
||||
ctx.push(UInstruction::Construct { dest: id, fields });
|
||||
Some(id)
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,8 @@ impl FnLowerable for PConstruct {
|
||||
impl PStruct {
|
||||
pub fn lower(
|
||||
&self,
|
||||
p: &mut IRUProgram,
|
||||
id: StructID,
|
||||
p: &mut UProgram,
|
||||
output: &mut CompilerOutput,
|
||||
span: FileSpan,
|
||||
) -> Option<()> {
|
||||
@@ -99,23 +100,30 @@ impl PStruct {
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, (name, ty))| {
|
||||
let id = FieldID(i);
|
||||
let id = FieldID::new(i);
|
||||
field_map.insert(name.clone(), id);
|
||||
StructField { name, ty }
|
||||
})
|
||||
.collect();
|
||||
p.def_struct(StructDef {
|
||||
name: self.name.as_ref()?.to_string(),
|
||||
origin: span,
|
||||
field_map,
|
||||
fields,
|
||||
});
|
||||
p.write(
|
||||
id,
|
||||
UStruct {
|
||||
origin: span,
|
||||
field_map,
|
||||
fields,
|
||||
},
|
||||
);
|
||||
Some(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Node<PStruct> {
|
||||
pub fn lower(&self, p: &mut IRUProgram, output: &mut CompilerOutput) {
|
||||
self.as_ref().map(|i| i.lower(p, output, self.span));
|
||||
pub fn lower_name(&self, p: &mut UProgram) -> Option<StructID> {
|
||||
let name = self.as_ref()?.name.as_ref()?.to_string();
|
||||
let id = p.def_searchable(name.to_string(), None);
|
||||
Some(id)
|
||||
}
|
||||
pub fn lower(&self, id: StructID, p: &mut UProgram, output: &mut CompilerOutput) {
|
||||
self.as_ref().map(|i| i.lower(id, p, output, self.span));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user