mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-22 16:08:24 +00:00
nice
This commit is contained in:
parent
40d71d6b83
commit
cdc52cef39
|
@ -85,7 +85,7 @@ pub fn main() -> Result<(), Box<dyn Error>> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let module_irs = lower_modules(&[module.clone()]);
|
||||
let (_symbols, module_irs) = lower_modules(&[module.clone()]);
|
||||
|
||||
if args.ir {
|
||||
println!("{:#?}", module_irs);
|
||||
|
|
|
@ -9,14 +9,14 @@ pub mod scalar_int;
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ModuleBody {
|
||||
pub module_id: usize,
|
||||
pub module_id: DefId,
|
||||
pub functions: BTreeMap<DefId, Body>,
|
||||
pub modules: BTreeMap<DefId, Self>,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
/// Definition id.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
|
||||
pub struct DefId {
|
||||
pub module_id: usize,
|
||||
pub id: usize,
|
||||
|
@ -105,6 +105,34 @@ pub enum TypeKind {
|
|||
FnDef(DefId, Vec<TypeInfo>), // The vec are generic types, not arg types
|
||||
}
|
||||
|
||||
impl TypeKind {
|
||||
pub fn get_falsy_value(&self) -> ValueTree {
|
||||
match self {
|
||||
Self::Bool => ValueTree::Leaf(ConstValue::Bool(false)),
|
||||
Self::Char => todo!(),
|
||||
Self::Int(ty) => match ty {
|
||||
IntTy::I8 => ValueTree::Leaf(ConstValue::I8(0)),
|
||||
IntTy::I16 => ValueTree::Leaf(ConstValue::I16(0)),
|
||||
IntTy::I32 => ValueTree::Leaf(ConstValue::I32(0)),
|
||||
IntTy::I64 => ValueTree::Leaf(ConstValue::I64(0)),
|
||||
IntTy::I128 => ValueTree::Leaf(ConstValue::I128(0)),
|
||||
IntTy::Isize => todo!(),
|
||||
},
|
||||
Self::Uint(ty) => match ty {
|
||||
UintTy::U8 => ValueTree::Leaf(ConstValue::U8(0)),
|
||||
UintTy::U16 => ValueTree::Leaf(ConstValue::U16(0)),
|
||||
UintTy::U32 => ValueTree::Leaf(ConstValue::U32(0)),
|
||||
UintTy::U64 => ValueTree::Leaf(ConstValue::U64(0)),
|
||||
UintTy::U128 => ValueTree::Leaf(ConstValue::U128(0)),
|
||||
UintTy::Usize => todo!(),
|
||||
},
|
||||
Self::Float(_) => todo!(),
|
||||
TypeKind::Unit => unreachable!(),
|
||||
TypeKind::FnDef(_, _) => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum IntTy {
|
||||
I128,
|
||||
|
@ -153,7 +181,9 @@ pub enum ValueTree {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum RValue {
|
||||
Use(Operand),
|
||||
Ref(bool, Operand),
|
||||
BinOp(BinOp, Operand, Operand),
|
||||
LogicOp(LogicalOp, Operand, Operand),
|
||||
UnOp(UnOp, Operand),
|
||||
}
|
||||
|
||||
|
@ -256,6 +286,13 @@ pub enum BinOp {
|
|||
Offset,
|
||||
}
|
||||
|
||||
// Diferent than BinOp because operands needs to be lazily evaluated.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum LogicalOp {
|
||||
And,
|
||||
Or,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum UnOp {
|
||||
Not,
|
||||
|
|
|
@ -21,6 +21,13 @@ impl IdGenerator {
|
|||
self.current_id
|
||||
}
|
||||
|
||||
pub fn module_defid(&self) -> DefId {
|
||||
DefId {
|
||||
module_id: self.module_id,
|
||||
id: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_defid(&mut self) -> DefId {
|
||||
let id = self.next_id();
|
||||
|
||||
|
@ -29,19 +36,27 @@ impl IdGenerator {
|
|||
id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_module_defid(&mut self) -> DefId {
|
||||
self.module_id += 1;
|
||||
self.current_id = 0;
|
||||
|
||||
self.module_defid()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct BuildCtx {
|
||||
pub module_name_to_id: HashMap<String, usize>,
|
||||
pub modules: HashMap<usize, ModuleCtx>,
|
||||
pub module_name_to_id: HashMap<String, DefId>,
|
||||
pub modules: HashMap<DefId, ModuleCtx>,
|
||||
pub functions: HashMap<DefId, Body>,
|
||||
pub module_id_counter: usize,
|
||||
pub gen: IdGenerator,
|
||||
pub symbol_names: HashMap<DefId, String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct ModuleCtx {
|
||||
pub id: usize,
|
||||
pub id: DefId,
|
||||
pub func_name_to_id: HashMap<String, DefId>,
|
||||
pub functions: HashMap<DefId, (Vec<TypeInfo>, TypeInfo)>,
|
||||
pub gen: IdGenerator,
|
||||
|
@ -49,7 +64,7 @@ pub struct ModuleCtx {
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BodyBuilder {
|
||||
pub local_module: usize,
|
||||
pub local_module: DefId,
|
||||
pub body: Body,
|
||||
pub statements: Vec<Statement>,
|
||||
pub locals: HashMap<String, usize>,
|
||||
|
|
|
@ -3,17 +3,29 @@ use std::collections::HashMap;
|
|||
use common::{BodyBuilder, BuildCtx, IdGenerator, ModuleCtx};
|
||||
use edlang_ast as ast;
|
||||
use edlang_ir as ir;
|
||||
use ir::{ConstData, ConstKind, Local, Operand, Place, Statement, Terminator, TypeInfo};
|
||||
use ir::{ConstData, ConstKind, DefId, Local, Operand, Place, Statement, Terminator, TypeInfo};
|
||||
|
||||
mod common;
|
||||
|
||||
pub fn lower_modules(modules: &[ast::Module]) -> Vec<ir::ModuleBody> {
|
||||
pub fn lower_modules(modules: &[ast::Module]) -> (HashMap<DefId, String>, Vec<ir::ModuleBody>) {
|
||||
let mut ctx = BuildCtx::default();
|
||||
|
||||
for m in modules {
|
||||
let module_id = ctx.gen.module_defid();
|
||||
ctx.module_name_to_id
|
||||
.insert(m.name.name.clone(), ctx.module_id_counter);
|
||||
ctx.module_id_counter += 1;
|
||||
.insert(m.name.name.clone(), ctx.gen.module_defid());
|
||||
ctx.symbol_names.insert(module_id, m.name.name.clone());
|
||||
|
||||
ctx.modules.insert(
|
||||
module_id,
|
||||
ModuleCtx {
|
||||
id: module_id,
|
||||
gen: IdGenerator::new(module_id.module_id),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
ctx.gen.next_module_defid();
|
||||
}
|
||||
|
||||
let mut lowered_modules = Vec::with_capacity(modules.len());
|
||||
|
@ -26,7 +38,7 @@ pub fn lower_modules(modules: &[ast::Module]) -> Vec<ir::ModuleBody> {
|
|||
lowered_modules.push(ir);
|
||||
}
|
||||
|
||||
lowered_modules
|
||||
(ctx.symbol_names, lowered_modules)
|
||||
}
|
||||
|
||||
fn lower_module(mut ctx: BuildCtx, module: &ast::Module) -> (BuildCtx, ir::ModuleBody) {
|
||||
|
@ -38,19 +50,18 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module) -> (BuildCtx, ir::Modul
|
|||
span: module.span,
|
||||
};
|
||||
|
||||
let mut module_ctx = ModuleCtx {
|
||||
id: body.module_id,
|
||||
gen: IdGenerator::new(body.module_id),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
for stmt in &module.contents {
|
||||
match stmt {
|
||||
ast::ModuleStatement::Function(func) => {
|
||||
let next_id = {
|
||||
let module_ctx = ctx.modules.get_mut(&module_id).unwrap();
|
||||
let next_id = module_ctx.gen.next_defid();
|
||||
module_ctx
|
||||
.func_name_to_id
|
||||
.insert(func.name.name.clone(), next_id);
|
||||
ctx.symbol_names.insert(next_id, func.name.name.clone());
|
||||
next_id
|
||||
};
|
||||
|
||||
let mut args = Vec::new();
|
||||
let ret_type;
|
||||
|
@ -69,18 +80,15 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module) -> (BuildCtx, ir::Modul
|
|||
args.push(ty);
|
||||
}
|
||||
|
||||
let module_ctx = ctx.modules.get_mut(&module_id).unwrap();
|
||||
module_ctx.functions.insert(next_id, (args, ret_type));
|
||||
}
|
||||
ast::ModuleStatement::Constant(_) => todo!(),
|
||||
ast::ModuleStatement::Struct(_) => todo!(),
|
||||
ast::ModuleStatement::Module(_) => todo!(),
|
||||
ast::ModuleStatement::Module(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
ctx.module_name_to_id
|
||||
.insert(module.name.name.clone(), body.module_id);
|
||||
ctx.modules.insert(body.module_id, module_ctx);
|
||||
|
||||
for stmt in &module.contents {
|
||||
match stmt {
|
||||
ast::ModuleStatement::Function(func) => {
|
||||
|
@ -100,7 +108,7 @@ fn lower_module(mut ctx: BuildCtx, module: &ast::Module) -> (BuildCtx, ir::Modul
|
|||
fn lower_function(
|
||||
mut ctx: BuildCtx,
|
||||
func: &ast::Function,
|
||||
module_id: usize,
|
||||
module_id: DefId,
|
||||
) -> (ir::Body, BuildCtx) {
|
||||
let def_id = *ctx
|
||||
.modules
|
||||
|
@ -226,7 +234,130 @@ fn lower_expr(
|
|||
ast::Expression::Value(info) => ir::RValue::Use(lower_value(builder, info, type_hint)),
|
||||
ast::Expression::FnCall(info) => ir::RValue::Use(lower_fn_call(builder, info)),
|
||||
ast::Expression::Unary(_, _) => todo!(),
|
||||
ast::Expression::Binary(_, _, _) => todo!(),
|
||||
ast::Expression::Binary(lhs, op, rhs) => {
|
||||
lower_binary_expr(builder, lhs, op, rhs, type_hint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_binary_expr(
|
||||
builder: &mut BodyBuilder,
|
||||
lhs: &ast::Expression,
|
||||
op: &ast::BinaryOp,
|
||||
rhs: &ast::Expression,
|
||||
type_hint: Option<&TypeInfo>,
|
||||
) -> ir::RValue {
|
||||
let expr_type = type_hint.expect("type hint needed");
|
||||
let lhs = {
|
||||
let rvalue = lower_expr(builder, lhs, type_hint);
|
||||
let local = builder.add_local(Local {
|
||||
mutable: false,
|
||||
span: None,
|
||||
ty: expr_type.clone(),
|
||||
kind: ir::LocalKind::Temp,
|
||||
});
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
kind: ir::StatementKind::StorageLive(local),
|
||||
});
|
||||
|
||||
let place = Place {
|
||||
local,
|
||||
projection: Default::default(),
|
||||
};
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
kind: ir::StatementKind::Assign(place.clone(), rvalue),
|
||||
});
|
||||
|
||||
place
|
||||
};
|
||||
let rhs = {
|
||||
let rvalue = lower_expr(builder, rhs, type_hint);
|
||||
let local = builder.add_local(Local {
|
||||
mutable: false,
|
||||
span: None,
|
||||
ty: expr_type.clone(),
|
||||
kind: ir::LocalKind::Temp,
|
||||
});
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
kind: ir::StatementKind::StorageLive(local),
|
||||
});
|
||||
|
||||
let place = Place {
|
||||
local,
|
||||
projection: Default::default(),
|
||||
};
|
||||
|
||||
builder.statements.push(Statement {
|
||||
span: None,
|
||||
kind: ir::StatementKind::Assign(place.clone(), rvalue),
|
||||
});
|
||||
|
||||
place
|
||||
};
|
||||
|
||||
match op {
|
||||
ast::BinaryOp::Arith(op, _) => match op {
|
||||
ast::ArithOp::Add => {
|
||||
ir::RValue::BinOp(ir::BinOp::Add, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::ArithOp::Sub => {
|
||||
ir::RValue::BinOp(ir::BinOp::Sub, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::ArithOp::Mul => {
|
||||
ir::RValue::BinOp(ir::BinOp::Mul, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::ArithOp::Div => {
|
||||
ir::RValue::BinOp(ir::BinOp::Div, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::ArithOp::Mod => {
|
||||
ir::RValue::BinOp(ir::BinOp::Rem, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
},
|
||||
ast::BinaryOp::Logic(op, _) => match op {
|
||||
ast::LogicOp::And => {
|
||||
ir::RValue::LogicOp(ir::LogicalOp::And, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::LogicOp::Or => {
|
||||
ir::RValue::LogicOp(ir::LogicalOp::Or, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
},
|
||||
ast::BinaryOp::Compare(op, _) => match op {
|
||||
ast::CmpOp::Eq => {
|
||||
ir::RValue::BinOp(ir::BinOp::Eq, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::CmpOp::NotEq => {
|
||||
ir::RValue::BinOp(ir::BinOp::Ne, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::CmpOp::Lt => {
|
||||
ir::RValue::BinOp(ir::BinOp::Lt, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::CmpOp::LtEq => {
|
||||
ir::RValue::BinOp(ir::BinOp::Le, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::CmpOp::Gt => {
|
||||
ir::RValue::BinOp(ir::BinOp::Gt, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::CmpOp::GtEq => {
|
||||
ir::RValue::BinOp(ir::BinOp::Ge, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
},
|
||||
ast::BinaryOp::Bitwise(op, _) => match op {
|
||||
ast::BitwiseOp::And => {
|
||||
ir::RValue::BinOp(ir::BinOp::BitAnd, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::BitwiseOp::Or => {
|
||||
ir::RValue::BinOp(ir::BinOp::BitOr, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
ast::BitwiseOp::Xor => {
|
||||
ir::RValue::BinOp(ir::BinOp::BitXor, Operand::Move(lhs), Operand::Move(rhs))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,7 +577,7 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> ir::Place {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn lower_type(ctx: &mut BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||
pub fn lower_type(_ctx: &mut BuildCtx, t: &ast::Type) -> ir::TypeInfo {
|
||||
match t.name.name.as_str() {
|
||||
"()" => ir::TypeInfo {
|
||||
span: Some(t.span),
|
||||
|
|
Loading…
Reference in a new issue