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
+2 -2
View File
@@ -174,7 +174,7 @@ pub fn arg_to_var(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<VarInst>
);
return None;
};
ctx.get_var(node)
ctx.var(node)
}
impl RegRef {
@@ -184,7 +184,7 @@ impl RegRef {
let reg = Reg::from_ident(node, ctx)?;
Self::Reg(reg)
}
PAsmArg::Ref(node) => Self::Var(ctx.get_var(node)?),
PAsmArg::Ref(node) => Self::Var(ctx.var(node)?),
})
}
}
+2 -2
View File
@@ -1,9 +1,9 @@
use crate::ir::{UProgram, UVar, VarInst};
use crate::ir::{UProgram, UVar, VarID, VarInst};
use super::{CompilerOutput, Node, PVarDef};
impl Node<PVarDef> {
pub fn lower(&self, program: &mut UProgram, output: &mut CompilerOutput) -> Option<VarInst> {
pub fn lower(&self, program: &mut UProgram, output: &mut CompilerOutput) -> Option<VarID> {
let s = self.as_ref()?;
let name = s.name.as_ref().map_or("{error}", |v| v);
let ty = match &s.ty {
+7 -7
View File
@@ -20,11 +20,11 @@ impl FnLowerable for PExpr {
Some(match e {
PExpr::Lit(l) => match l {
super::PLiteral::String(s) => {
let dest = ctx.b.temp_var(ctx.origin, Type::Bits(8).slice());
let dest = ctx.b.temp_var(ctx.origin, Type::Bits(8).slice(ctx.b.p));
let data = s.as_bytes().to_vec();
let src = ctx.b.def_data(UData {
name: format!("string \"{}\"", s.replace("\n", "\\n")),
ty: Type::Bits(8).arr(data.len() as u32),
ty: Type::Bits(8).arr(ctx.b.p, data.len() as u32),
content: data,
});
ctx.push(UInstruction::LoadSlice { dst: dest, src });
@@ -55,7 +55,7 @@ impl FnLowerable for PExpr {
}
super::PLiteral::Unit => ctx.b.temp_var(ctx.origin, Type::Unit),
},
PExpr::Ident(i) => ctx.get_var(i),
PExpr::Ident(i) => ctx.var(i),
PExpr::BinaryOp(op, e1, e2) => match op {
InfixOp::Add => todo!(),
InfixOp::Sub => todo!(),
@@ -77,13 +77,13 @@ impl FnLowerable for PExpr {
let res = e.lower(ctx)?;
match op {
PostfixOp::Ref => {
let ty = ctx.b.vars[res.id].ty.rf();
let ty = Type::Ref(ctx.b.infer());
let dest = ctx.temp(ty);
ctx.push(UInstruction::Ref { dst: dest, src: res });
dest
}
PostfixOp::Deref => {
let ty = ctx.b.vars[res.id].ty.derf();
let ty = Type::Deref(ctx.b.infer());
let dest = ctx.temp(ty);
ctx.push(UInstruction::Deref { dst: dest, src: res });
dest
@@ -100,9 +100,9 @@ impl FnLowerable for PExpr {
let arg = arg.lower(ctx)?;
nargs.push(arg);
}
let dest = ctx.temp(Type::Placeholder);
let dest = ctx.temp(Type::Infer);
ctx.push(UInstruction::Call {
dst: dest,
dst: VarInst { status: , origin: () },
f: fe,
args: nargs,
});
+61 -84
View File
@@ -3,120 +3,111 @@ use std::collections::HashMap;
use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Imports, Node, PFunction};
use crate::{
ir::{
FnID, Idents, Typable, Type, UFunc, UInstrInst, UInstruction, UModuleBuilder, UProgram,
UVar, VarID, VarInst,
FnID, Origin, Typable, Type, UFunc, UInstrInst, UInstruction, UModuleBuilder, UVar, VarID,
VarInst, VarStatus,
},
parser,
parser, util::NameStack,
};
impl Node<PFunction> {
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
self.as_ref()?.lower_name(p)
}
pub fn lower(
&self,
id: FnID,
p: &mut UProgram,
b: &mut UModuleBuilder,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
if let Some(s) = self.as_ref() {
s.lower(id, p, imports, output)
}
) -> Option<FnID> {
self.as_ref()
.map(|s| s.lower(b, imports, output, self.origin))
.flatten()
}
}
impl PFunction {
pub fn lower_name(&self, p: &mut UProgram) -> Option<FnID> {
let header = self.header.as_ref()?;
let name = header.name.as_ref()?;
let id = p.def_searchable(name, None, self.header.origin);
Some(id)
}
pub fn lower(
&self,
id: FnID,
p: &mut UProgram,
b: &mut UModuleBuilder,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
let name = p.names.name(id).to_string();
p.push_name(&name);
let (args, ret) = if let Some(header) = self.header.as_ref() {
origin: Origin,
) -> Option<FnID> {
let header = self.header.as_ref()?;
let name = header.name.as_ref()?.0.clone();
let (generic_args, args, ret) = if let Some(header) = self.header.as_ref() {
(
header
.gargs
.iter()
.map(|a| Some(a.lower(b, output)))
.collect(),
header
.args
.iter()
.flat_map(|a| Some(a.lower(p, output)?.id))
.flat_map(|a| Some(a.lower(b, output)?))
.collect(),
match &header.ret {
Some(ty) => ty.lower(p, output),
None => Type::Unit,
Some(ty) => ty.lower(b, output),
None => b.def_ty(Type::Unit),
},
)
} else {
(Vec::new(), Type::Error)
(Vec::new(), Vec::new(), b.error)
};
let mut ctx = FnLowerCtx {
instructions: Vec::new(),
b: p,
output,
origin: self.body.origin,
imports,
let instructions = {
let mut var_stack = Vec::new();
let mut ctx = FnLowerCtx {
instructions: Vec::new(),
var_stack: &mut var_stack,
b,
output,
origin: self.body.origin,
imports,
};
if let Some(src) = self.body.lower(&mut ctx) {
ctx.instructions.push(UInstrInst {
origin: src.origin,
i: UInstruction::Ret { src },
});
}
ctx.instructions
};
if let Some(src) = self.body.lower(&mut ctx) {
ctx.instructions.push(UInstrInst {
i: UInstruction::Ret { src },
origin: src.origin,
});
}
let instructions = ctx.instructions;
let gargs = args.iter().map(|a| b.vars[a].ty).collect();
let f = UFunc {
origin,
gargs,
name,
args,
ret,
instructions,
};
p.pop_name();
p.write(id, f)
Some(b.def_fn(f))
}
}
pub struct FnLowerCtx<'a> {
pub b: &'a mut UModuleBuilder<'a>,
pub struct FnLowerCtx<'a, 'b> {
pub b: &'a mut UModuleBuilder<'b>,
pub instructions: Vec<UInstrInst>,
pub output: &'a mut CompilerOutput,
pub origin: FileSpan,
pub imports: &'a mut Imports,
pub var_stack: Vec<HashMap<String, VarID>>,
pub var_stack: &'a mut NameStack<VarID>,
}
impl FnLowerCtx<'_> {
pub fn get_idents(&mut self, node: &Node<parser::PIdent>) -> Option<Idents> {
let name = node.inner.as_ref()?;
let res = self.b.get_idents(name);
if res.is_none() {
self.err_at(node.origin, format!("Identifier '{}' not found", name));
impl<'a, 'b> FnLowerCtx<'a, 'b> {
pub fn var(&mut self, node: &Node<parser::PIdent>) -> VarInst {
if let Some(n) = node.as_ref() {
if let Some(&var) = self.var_stack.search(&n.0) {
return VarInst {
status: VarStatus::Res(var),
origin: node.origin,
}
}
}
res
}
pub fn get_var(&mut self, node: &Node<parser::PIdent>) -> VarInst {
let ids = self.get_idents(node)?;
if ids.get::<UVar>().is_none() {
self.err_at(
node.origin,
format!("Variable '{}' not found", node.inner.as_ref()?),
);
}
ids.get::<UVar>().map(|id| VarInst {
id,
origin: node.origin,
})
}
pub fn err(&mut self, msg: String) {
self.output.err(CompilerMsg::new(self.origin, msg))
self.output.err(CompilerMsg::new(msg, self.origin))
}
pub fn err_at(&mut self, span: FileSpan, msg: String) {
self.output.err(CompilerMsg::new(span, msg))
self.output.err(CompilerMsg::new(msg, span))
}
pub fn temp<T: Typable>(&mut self, ty: Type) -> VarInst {
self.b.temp_var(self.origin, ty)
@@ -125,27 +116,13 @@ impl FnLowerCtx<'_> {
self.push_at(i, self.origin);
}
pub fn push_at(&mut self, i: UInstruction, span: FileSpan) {
match i {
UInstruction::Mv { dst: dest, src } => todo!(),
UInstruction::Ref { dst: dest, src } => todo!(),
UInstruction::LoadData { dst: dest, src } => todo!(),
UInstruction::LoadSlice { dst: dest, src } => todo!(),
UInstruction::LoadFn { dst: dest, src } => todo!(),
UInstruction::Call { dst: dest, f, args } => todo!(),
UInstruction::AsmBlock { instructions, args } => todo!(),
UInstruction::Ret { src } => todo!(),
UInstruction::Construct { dst: dest, fields } => todo!(),
UInstruction::If { cond, body } => todo!(),
UInstruction::Loop { body } => todo!(),
UInstruction::Break => todo!(),
UInstruction::Continue => todo!(),
}
self.instructions.push(UInstrInst { i, origin: span });
}
pub fn branch<'a>(&'a mut self) -> FnLowerCtx<'a> {
pub fn branch(&'a mut self) -> FnLowerCtx<'a, 'b> {
FnLowerCtx {
b: self.b,
instructions: Vec::new(),
var_stack: self.var_stack,
output: self.output,
origin: self.origin,
imports: self.imports,
+2 -2
View File
@@ -8,13 +8,13 @@ mod struc;
mod ty;
use super::*;
use crate::ir::{Type, UFunc, UProgram};
use crate::ir::{Type, UFunc, UModuleBuilder};
impl PModule {
pub fn lower(
&self,
path: Vec<String>,
p: &mut UProgram,
p: &mut UModuleBuilder,
imports: &mut Imports,
output: &mut CompilerOutput,
) {
+7 -31
View File
@@ -9,14 +9,14 @@ impl Node<Box<PType>> {
pub fn lower(&self, p: &mut UModuleBuilder, output: &mut CompilerOutput) -> TypeID {
self.as_ref()
.map(|t| t.lower(p, output, self.origin))
.unwrap_or(p.error())
.unwrap_or(p.error)
}
}
impl Node<PType> {
pub fn lower(&self, p: &mut UModuleBuilder, output: &mut CompilerOutput) -> TypeID {
self.as_ref()
.map(|t| t.lower(p, output, self.origin))
.unwrap_or(p.error())
.unwrap_or(p.error)
}
}
@@ -34,7 +34,7 @@ impl PType {
while let PType::Member(node, ident) = ty {
ty = if let Some(t) = node.as_ref() {
let Some(name) = ident.as_ref() else {
return p.error();
return p.error;
};
origin = node.origin;
path.push(MemberID {
@@ -43,18 +43,19 @@ impl PType {
});
&**t
} else {
return p.error();
return p.error;
};
}
if !path.is_empty() {
let PType::Ident(id) = ty else {
return p.error();
return p.error;
};
path.push(MemberID {
name: id.0.clone(),
origin,
});
return p.def_ty(Type::Unres(ModPath { m: p.module, path }));
let ty = Type::Unres(ModPath { m: p.module, path });
return p.def_ty(ty);
}
let ty = match ty {
PType::Member(_, _) => unreachable!(),
@@ -70,31 +71,6 @@ impl PType {
PType::Generic(node, nodes) => todo!(),
};
p.def_ty(ty)
// let Some(name) = self.name.as_ref() else {
// return p.error();
// };
// let ids = p.get_idents(name);
// // TODO: should generics always take precedence?
// if let Some(id) = ids.and_then(|ids| ids.get::<Type>()) {
// Type::Generic { id }
// } else if let Some(id) = ids.and_then(|ids| ids.get::<UStruct>()) {
// let args = self.args.iter().map(|n| n.lower(p, output)).collect();
// Type::Struct(StructInst { id, args })
// } else if let Ok(num) = name.parse::<u32>() {
// Type::Bits(num)
// } else {
// match name.as_str() {
// "slice" => {
// let inner = self.args[0].lower(p, output);
// Type::Slice(Box::new(inner))
// }
// "_" => Type::Infer,
// _ => {
// output.err(CompilerMsg::from_span(span, "Type not found".to_string()));
// Type::Error
// }
// }
// }
}
}
+10 -2
View File
@@ -1,12 +1,13 @@
use super::{
util::parse_list, PBlock, PIdent, Node, Parsable, ParseResult, ParserCtx,
Symbol, PType, PVarDef,
util::parse_list, Node, PBlock, PIdent, PType, PVarDef, Parsable, ParseResult, ParserCtx,
Symbol,
};
use std::fmt::Debug;
pub struct PFunctionHeader {
pub name: Node<PIdent>,
pub args: Vec<Node<PVarDef>>,
pub gargs: Vec<Node<PType>>,
pub ret: Option<Node<PType>>,
}
@@ -18,6 +19,12 @@ pub struct PFunction {
impl Parsable for PFunctionHeader {
fn parse(ctx: &mut ParserCtx) -> ParseResult<Self> {
let name = ctx.parse()?;
let generic_args = if ctx.expect_peek()?.is_symbol(Symbol::OpenAngle) {
ctx.next();
parse_list(ctx, Symbol::CloseAngle)?
} else {
Vec::new()
};
ctx.expect_sym(Symbol::OpenParen)?;
// let sel = ctx.maybe_parse();
// if sel.is_some() {
@@ -39,6 +46,7 @@ impl Parsable for PFunctionHeader {
ParseResult::Ok(Self {
name,
args,
gargs: generic_args,
ret,
})
}
+1 -1
View File
@@ -40,7 +40,7 @@ impl Parsable for PType {
}
break;
}
ParseResult::Wrap(cur)
ParseResult::Node(cur)
}
}