type checking !?!?
This commit is contained in:
@@ -3,7 +3,7 @@ use crate::{
|
||||
compiler::arch::riscv64::*,
|
||||
ir::{
|
||||
arch::riscv64::{RV64Instruction, RegRef},
|
||||
VarID,
|
||||
VarInst,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -57,7 +57,7 @@ impl RV64Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn arg_to_var(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<VarID> {
|
||||
pub fn arg_to_var(node: &Node<PAsmArg>, ctx: &mut FnLowerCtx) -> Option<VarInst> {
|
||||
let PAsmArg::Ref(node) = node.inner.as_ref()? else {
|
||||
ctx.err_at(
|
||||
node.span,
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::{
|
||||
compiler::arch::riscv64::Reg,
|
||||
ir::{arch::riscv64::RV64Instruction, IRUInstruction, VarID},
|
||||
ir::{arch::riscv64::RV64Instruction, IRUInstruction, VarInst},
|
||||
};
|
||||
|
||||
use super::{PAsmBlock, PAsmBlockArg, FnLowerCtx, FnLowerable, PInstruction};
|
||||
use super::{FnLowerCtx, FnLowerable, PAsmBlock, PAsmBlockArg, PInstruction};
|
||||
|
||||
impl FnLowerable for PInstruction {
|
||||
type Output = RV64Instruction;
|
||||
@@ -43,7 +43,7 @@ impl FnLowerable for PAsmBlock {
|
||||
}
|
||||
|
||||
impl FnLowerable for PAsmBlockArg {
|
||||
type Output = (Reg, VarID);
|
||||
type Output = (Reg, VarInst);
|
||||
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<Self::Output> {
|
||||
let var = ctx.get_var(&self.var)?;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::ir::{IRUInstruction, VarID};
|
||||
use crate::ir::{IRUInstruction, VarInst};
|
||||
|
||||
use super::{PBlock, FnLowerCtx, FnLowerable, PStatement};
|
||||
use super::{FnLowerCtx, FnLowerable, PBlock, PStatement};
|
||||
|
||||
impl FnLowerable for PBlock {
|
||||
type Output = VarID;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarID> {
|
||||
type Output = VarInst;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
|
||||
let ctx = &mut ctx.sub();
|
||||
for statement in &self.statements {
|
||||
statement.lower(ctx);
|
||||
@@ -14,20 +14,20 @@ impl FnLowerable for PBlock {
|
||||
}
|
||||
|
||||
impl FnLowerable for PStatement {
|
||||
type Output = VarID;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarID> {
|
||||
type Output = VarInst;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
|
||||
match self {
|
||||
super::PStatement::Let(def, e) => {
|
||||
let def = def.lower(ctx.map, ctx.output)?;
|
||||
let res = e.lower(ctx);
|
||||
if let Some(res) = res {
|
||||
ctx.map.name_var(&def, res);
|
||||
ctx.map.name_var(&def, res.id);
|
||||
}
|
||||
None
|
||||
}
|
||||
super::PStatement::Return(e) => {
|
||||
let src = e.lower(ctx)?;
|
||||
ctx.push(IRUInstruction::Ret { src });
|
||||
ctx.push_at(IRUInstruction::Ret { src }, src.span);
|
||||
None
|
||||
}
|
||||
super::PStatement::Expr(e) => e.lower(ctx),
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::ir::{FileSpan, NamespaceGuard, Origin, Type, VarDef};
|
||||
use crate::ir::{NamespaceGuard, Origin, Type, VarDef};
|
||||
|
||||
use super::{Node, PType, PVarDef, ParserMsg, ParserOutput};
|
||||
use super::{CompilerMsg, CompilerOutput, FileSpan, Node, PType, PVarDef};
|
||||
|
||||
impl Node<PVarDef> {
|
||||
pub fn lower(
|
||||
&self,
|
||||
namespace: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
) -> Option<VarDef> {
|
||||
let s = self.as_ref()?;
|
||||
let name = s.name.as_ref()?.to_string();
|
||||
@@ -23,7 +23,7 @@ impl Node<PVarDef> {
|
||||
}
|
||||
|
||||
impl Node<PType> {
|
||||
pub fn lower(&self, namespace: &mut NamespaceGuard, output: &mut ParserOutput) -> Type {
|
||||
pub fn lower(&self, namespace: &mut NamespaceGuard, output: &mut CompilerOutput) -> Type {
|
||||
self.as_ref()
|
||||
.map(|t| t.lower(namespace, output, self.span))
|
||||
.unwrap_or(Type::Error)
|
||||
@@ -34,7 +34,7 @@ impl PType {
|
||||
pub fn lower(
|
||||
&self,
|
||||
namespace: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
span: FileSpan,
|
||||
) -> Type {
|
||||
match namespace.get(&self.name).and_then(|ids| ids.ty) {
|
||||
@@ -60,7 +60,7 @@ impl PType {
|
||||
Type::Slice(Box::new(inner))
|
||||
}
|
||||
_ => {
|
||||
output.err(ParserMsg::from_span(span, "Type not found".to_string()));
|
||||
output.err(CompilerMsg::from_span(span, "Type not found".to_string()));
|
||||
Type::Error
|
||||
}
|
||||
}
|
||||
|
||||
+33
-15
@@ -1,31 +1,48 @@
|
||||
use super::{func::FnLowerCtx, FnLowerable, PExpr, UnaryOp};
|
||||
use crate::ir::{IRUInstruction, Size, Type, VarID};
|
||||
use crate::ir::{DataDef, IRUInstruction, Origin, Type, VarInst};
|
||||
|
||||
impl FnLowerable for PExpr {
|
||||
type Output = VarID;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarID> {
|
||||
type Output = VarInst;
|
||||
fn lower(&self, ctx: &mut FnLowerCtx) -> Option<VarInst> {
|
||||
Some(match self {
|
||||
PExpr::Lit(l) => match l.as_ref()? {
|
||||
super::PLiteral::String(s) => {
|
||||
let dest = ctx.map.temp_var(l.span, Type::Bits(8).slice());
|
||||
let data = s.as_bytes().to_vec();
|
||||
let len = data.len() as Size;
|
||||
let src = ctx.map.def_data(data);
|
||||
ctx.push(IRUInstruction::LoadSlice { dest, src, len });
|
||||
let src = ctx.map.def_data(
|
||||
DataDef {
|
||||
ty: Type::Bits(8).arr(data.len() as u32),
|
||||
origin: Origin::File(l.span),
|
||||
},
|
||||
data,
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadSlice { dest, src });
|
||||
dest
|
||||
}
|
||||
super::PLiteral::Char(c) => {
|
||||
let dest = ctx.map.temp_var(l.span, Type::Bits(8).slice());
|
||||
let src = ctx.map.def_data(c.to_string().as_bytes().to_vec());
|
||||
let ty = Type::Bits(8);
|
||||
let dest = ctx.map.temp_var(l.span, ty.clone());
|
||||
let src = ctx.map.def_data(
|
||||
DataDef {
|
||||
ty,
|
||||
origin: Origin::File(l.span),
|
||||
},
|
||||
c.to_string().as_bytes().to_vec(),
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadData { dest, src });
|
||||
dest
|
||||
}
|
||||
super::PLiteral::Number(n) => {
|
||||
// TODO: temp
|
||||
let ty = Type::Bits(64);
|
||||
let dest = ctx.map.temp_var(l.span, Type::Bits(64));
|
||||
let src = ctx
|
||||
.map
|
||||
.def_data(n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec());
|
||||
let src = ctx.map.def_data(
|
||||
DataDef {
|
||||
ty,
|
||||
origin: Origin::File(l.span),
|
||||
},
|
||||
n.whole.parse::<i64>().unwrap().to_le_bytes().to_vec(),
|
||||
);
|
||||
ctx.push(IRUInstruction::LoadData { dest, src });
|
||||
dest
|
||||
}
|
||||
@@ -44,7 +61,7 @@ impl FnLowerable for PExpr {
|
||||
let res = e.lower(ctx)?;
|
||||
match op {
|
||||
UnaryOp::Ref => {
|
||||
let temp = ctx.temp(ctx.map.get_var(res).ty.clone());
|
||||
let temp = ctx.temp(ctx.map.get_var(res.id).ty.clone());
|
||||
ctx.push(IRUInstruction::Ref {
|
||||
dest: temp,
|
||||
src: res,
|
||||
@@ -52,7 +69,7 @@ impl FnLowerable for PExpr {
|
||||
temp
|
||||
}
|
||||
UnaryOp::Deref => {
|
||||
let t = &ctx.map.get_var(res).ty;
|
||||
let t = &ctx.map.get_var(res.id).ty;
|
||||
let Type::Ref(inner) = t else {
|
||||
ctx.err(format!(
|
||||
"Cannot dereference type {:?}",
|
||||
@@ -77,7 +94,7 @@ impl FnLowerable for PExpr {
|
||||
let arg = arg.lower(ctx)?;
|
||||
nargs.push(arg);
|
||||
}
|
||||
let def = ctx.map.get_fn_var(fe);
|
||||
let def = ctx.map.get_fn_var(fe.id);
|
||||
let ty = match def {
|
||||
Some(def) => def.ret.clone(),
|
||||
None => {
|
||||
@@ -85,7 +102,7 @@ impl FnLowerable for PExpr {
|
||||
e.span,
|
||||
format!(
|
||||
"Expected function, found {}",
|
||||
ctx.map.type_name(&ctx.map.get_var(fe).ty)
|
||||
ctx.map.type_name(&ctx.map.get_var(fe.id).ty)
|
||||
),
|
||||
);
|
||||
Type::Error
|
||||
@@ -100,6 +117,7 @@ impl FnLowerable for PExpr {
|
||||
temp
|
||||
}
|
||||
PExpr::Group(e) => e.lower(ctx)?,
|
||||
PExpr::Construct(c) => todo!(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+21
-15
@@ -1,8 +1,8 @@
|
||||
use super::{FnLowerable, Node, PFunction, ParserMsg, ParserOutput};
|
||||
use super::{CompilerMsg, CompilerOutput, FileSpan, FnLowerable, Node, PFunction};
|
||||
use crate::{
|
||||
ir::{
|
||||
FileSpan, FnDef, FnID, IRInstructions, IRUFunction, IRUInstruction, Idents, NamespaceGuard,
|
||||
Origin, Type, VarDef, VarID,
|
||||
FnDef, FnID, IRInstructions, IRUFunction, IRUInstruction, Idents, NamespaceGuard, Origin,
|
||||
Type, VarDef, VarID, VarInst,
|
||||
},
|
||||
parser,
|
||||
};
|
||||
@@ -11,7 +11,7 @@ impl Node<PFunction> {
|
||||
pub fn lower_header(
|
||||
&self,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
) -> Option<FnID> {
|
||||
self.as_ref()?.lower_header(map, output)
|
||||
}
|
||||
@@ -19,7 +19,7 @@ impl Node<PFunction> {
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
) -> Option<IRUFunction> {
|
||||
Some(self.as_ref()?.lower_body(id, map, output))
|
||||
}
|
||||
@@ -29,7 +29,7 @@ impl PFunction {
|
||||
pub fn lower_header(
|
||||
&self,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
) -> Option<FnID> {
|
||||
let header = self.header.as_ref()?;
|
||||
let name = header.name.as_ref()?;
|
||||
@@ -59,7 +59,7 @@ impl PFunction {
|
||||
&self,
|
||||
id: FnID,
|
||||
map: &mut NamespaceGuard,
|
||||
output: &mut ParserOutput,
|
||||
output: &mut CompilerOutput,
|
||||
) -> IRUFunction {
|
||||
let mut instructions = IRInstructions::new();
|
||||
let def = map.get_fn(id).clone();
|
||||
@@ -71,7 +71,7 @@ impl PFunction {
|
||||
span: self.body.span,
|
||||
};
|
||||
if let Some(src) = self.body.lower(&mut ctx) {
|
||||
instructions.push(IRUInstruction::Ret { src });
|
||||
instructions.push(IRUInstruction::Ret { src }, src.span);
|
||||
}
|
||||
IRUFunction::new(def.name.clone(), args, instructions)
|
||||
}
|
||||
@@ -80,7 +80,7 @@ impl PFunction {
|
||||
pub struct FnLowerCtx<'a, 'n> {
|
||||
pub map: &'a mut NamespaceGuard<'n>,
|
||||
pub instructions: &'a mut IRInstructions,
|
||||
pub output: &'a mut ParserOutput,
|
||||
pub output: &'a mut CompilerOutput,
|
||||
pub span: FileSpan,
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ impl<'n> FnLowerCtx<'_, 'n> {
|
||||
}
|
||||
res
|
||||
}
|
||||
pub fn get_var(&mut self, node: &Node<parser::PIdent>) -> Option<VarID> {
|
||||
pub fn get_var(&mut self, node: &Node<parser::PIdent>) -> Option<VarInst> {
|
||||
let ids = self.get(node)?;
|
||||
if ids.var.is_none() {
|
||||
self.err_at(
|
||||
@@ -112,19 +112,25 @@ impl<'n> FnLowerCtx<'_, 'n> {
|
||||
),
|
||||
);
|
||||
}
|
||||
ids.var
|
||||
ids.var.map(|id| VarInst {
|
||||
id,
|
||||
span: node.span,
|
||||
})
|
||||
}
|
||||
pub fn err(&mut self, msg: String) {
|
||||
self.output.err(ParserMsg::from_span(self.span, msg))
|
||||
self.output.err(CompilerMsg::from_span(self.span, msg))
|
||||
}
|
||||
pub fn err_at(&mut self, span: FileSpan, msg: String) {
|
||||
self.output.err(ParserMsg::from_span(span, msg))
|
||||
self.output.err(CompilerMsg::from_span(span, msg))
|
||||
}
|
||||
pub fn temp(&mut self, ty: Type) -> VarID {
|
||||
pub fn temp(&mut self, ty: Type) -> VarInst {
|
||||
self.map.temp_var(self.span, ty)
|
||||
}
|
||||
pub fn push(&mut self, i: IRUInstruction) {
|
||||
self.instructions.push(i);
|
||||
self.instructions.push(i, self.span);
|
||||
}
|
||||
pub fn push_at(&mut self, i: IRUInstruction, span: FileSpan) {
|
||||
self.instructions.push(i, span);
|
||||
}
|
||||
pub fn sub<'b>(&'b mut self) -> FnLowerCtx<'b, 'n> {
|
||||
FnLowerCtx {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use crate::ir::NamespaceGuard;
|
||||
|
||||
use super::{PModule, ParserOutput};
|
||||
use super::{PModule, CompilerOutput};
|
||||
|
||||
impl PModule {
|
||||
pub fn lower(&self, map: &mut NamespaceGuard, output: &mut ParserOutput) {
|
||||
pub fn lower(&self, map: &mut NamespaceGuard, output: &mut CompilerOutput) {
|
||||
let mut fns = Vec::new();
|
||||
for f in &self.functions {
|
||||
if let Some(id) = f.lower_header(map, output) {
|
||||
|
||||
Reference in New Issue
Block a user