moving to desktop
This commit is contained in:
@@ -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)?),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
) {
|
||||
|
||||
@@ -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
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ impl Parsable for PType {
|
||||
}
|
||||
break;
|
||||
}
|
||||
ParseResult::Wrap(cur)
|
||||
ParseResult::Node(cur)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user