From 4826e6a8fd5b0098b726e187b7400d8a799e4856 Mon Sep 17 00:00:00 2001 From: Alexander Hansen Date: Tue, 13 Aug 2024 08:44:25 -0700 Subject: [PATCH] wip --- petr-lower/src/error.rs | 10 -- petr-lower/src/lib.rs | 60 +++++++++-- petr-lower/src/opcodes.rs | 219 -------------------------------------- 3 files changed, 53 insertions(+), 236 deletions(-) delete mode 100644 petr-lower/src/error.rs delete mode 100644 petr-lower/src/opcodes.rs diff --git a/petr-lower/src/error.rs b/petr-lower/src/error.rs deleted file mode 100644 index 01661b3..0000000 --- a/petr-lower/src/error.rs +++ /dev/null @@ -1,10 +0,0 @@ -use miette::Diagnostic; -use thiserror::Error; - -#[derive(Debug, Error, Diagnostic, Clone)] -pub enum LoweringError { - #[error("Internal compiler error: {0}")] - Internal(String), - #[error("Unable to infer type")] - UnableToInferType, -} diff --git a/petr-lower/src/lib.rs b/petr-lower/src/lib.rs index 5dd4f83..bdbcd3f 100644 --- a/petr-lower/src/lib.rs +++ b/petr-lower/src/lib.rs @@ -1,25 +1,71 @@ use std::collections::BTreeMap; +use petr_typecheck::TypedExpr; + trait Lowerer { type Target; - fn lower_expr(&mut self, expr: &TypedExpr) -> Result; -} + type Error; + fn lower_expr( + &mut self, + expr: &TypedExpr, + ) -> Result; +} struct JsFunction { name: String, args: Vec, - body: Vec, + body: Vec, } -enum Js{ +enum Js { Return(Box), - Assign(String, JsExpr), + Assign(String, Box), Call(String, Vec), + Literal(JsLiteral), +} + +enum JsLiteral { + String(String), + Int(i64), + Float(f64), } /// Lowers Petr into Javascript. -struct JSLowerer { - functions: BTreeMap; +struct JSLowerer { + functions: BTreeMap, } +struct JsLoweringError { + kind: JsLoweringErrorKind, +} + +enum JsLoweringErrorKind {} + +impl Lowerer for JSLowerer { + type Error = JsLoweringError; + type Target = Js; + + fn lower_expr( + &mut self, + expr: &TypedExpr, + ) -> Result { + use petr_typecheck::TypedExprKind::*; + match &expr.kind { + FunctionCall { func, args, ty } => todo!(), + Literal { value, ty } => todo!(), + List { elements, ty } => todo!(), + Unit => todo!(), + Variable { ty, name } => todo!(), + Intrinsic { ty, intrinsic } => todo!(), + ErrorRecovery(_) => todo!(), + ExprWithBindings { bindings, expression } => todo!(), + TypeConstructor { ty, args } => todo!(), + If { + condition, + then_branch, + else_branch, + } => todo!(), + } + } +} diff --git a/petr-lower/src/opcodes.rs b/petr-lower/src/opcodes.rs deleted file mode 100644 index e3373d2..0000000 --- a/petr-lower/src/opcodes.rs +++ /dev/null @@ -1,219 +0,0 @@ -use petr_utils::idx_map_key; - -use crate::MonomorphizedFunctionId; - -idx_map_key!(FunctionLabel); - -idx_map_key!(DataLabel); - -macro_rules! ir_ops { - ($($(#[$attr:meta])* - $op_name:ident $op_code:literal $($args:ty: $arg_name:ident),* - );+) => { - - #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] - pub enum IrOpcode { - $( - $(#[$attr])* - $op_name($($args),*), - )+ - } - - - impl std::fmt::Display for IrOpcode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - $( - IrOpcode::$op_name($($arg_name),*) => { - write!(f, "{}", $op_code)?; - $( - write!(f, " {}", $arg_name)?; - )* - Ok(()) - } - )+ - } - } - } - - // TODO serialize/deserialize using above display - }; -} - -ir_ops! { - JumpImmediateFunction "fjumpi" MonomorphizedFunctionId: imm; - Jump "jump" Reg: dest; - Add "add" Reg: dest, Reg: lhs, Reg: rhs; - Multiply "mult" Reg: dest, Reg: lhs, Reg: rhs; - Subtract "sub" Reg: dest, Reg: lhs, Reg: rhs; - Divide "div" Reg: dest, Reg: lhs, Reg: rhs; - LoadData "ld" Reg: dest, DataLabel: data; - StackPop "pop" Reg: dest; - StackPush "push" Reg: src; - Intrinsic "intrinsic" Intrinsic: intr; - FunctionLabel "func" MonomorphizedFunctionId: label; - LoadImmediate "imm" Reg: dest, u64: imm; - Copy "cp" Reg: dest, Reg: src; - Label "label" LabelId: label; - Return "ret" Reg: return_value; - ReturnImmediate "reti" u64: imm; - PushPc "ppc"; - StackPushImmediate "pushi" u64: imm; - Malloc "malloc" Reg: ptr_dest, Reg: size; - MallocImmediate "malloci" Reg: ptr_dest, Size: imm; - /// Register `src` will itself have its value written to the memory pointed to by `dest_ptr` - WriteRegisterToMemory "sri" Reg: src, Reg: dest_ptr; - Comment "comment" String: comment; - JumpIfFalseImmediate "cjump" Reg: cond, LabelId: dest; - JumpImmediate "jumpi" LabelId: dest; - Equal "eq" Reg: dest, Reg: lhs, Reg: rhs -} - -idx_map_key!(LabelId); - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum Intrinsic { - // given a pointer, print the thing it points to - Puts(Reg), -} - -impl std::fmt::Display for Intrinsic { - fn fmt( - &self, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - write!( - f, - "@{}", - match self { - Intrinsic::Puts(x) => format!("puts({x})"), - } - ) - } -} - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub enum IrTy { - Ptr(Box), - Int64, - Unit, - String, - Boolean, - UserDefinedType { - variants: Vec, - constant_literal_types: Vec, - }, - List(Box), -} - -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct IrUserDefinedTypeVariant { - pub fields: Vec, -} - -impl IrUserDefinedTypeVariant { - pub fn size(&self) -> Size { - // the size of a product type is the sum of the sizes of its fields - self.fields.iter().map(|f| f.size().num_bytes()).sum::().into() - } -} - -impl IrTy { - pub fn size(&self) -> Size { - match self { - IrTy::Int64 => 8, - IrTy::Ptr(_) => 8, - IrTy::Unit => 0, - // size of the pointer to the string - IrTy::String => 8, - IrTy::Boolean => 1, - // the size of a sum type is the size of the largest variant - IrTy::UserDefinedType { - variants, - constant_literal_types, - } => { - return variants - .iter() - .map(|v| v.size()) - .chain(constant_literal_types.iter().map(|t| t.size())) - .max() - .expect("user defined type should have at least one variant") - }, - IrTy::List(ty) => { - // the size of a list is the size of a pointer - // to the first element - return IrTy::Ptr(ty.clone()).size(); - }, - } - .into() - } - - pub(crate) fn is_copy_type(&self) -> bool { - self.size().num_bytes() <= 8 - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct Size(T) -where - T: SizeUnit; - -impl std::fmt::Debug for Size { - fn fmt( - &self, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - write!(f, "{:?} bytes", self.0.num_bytes()) - } -} - -impl std::fmt::Display for Size { - fn fmt( - &self, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - write!(f, "{} bytes", self.0.num_bytes()) - } -} - -impl Size { - pub fn num_bytes(&self) -> usize { - self.0.num_bytes() - } -} - -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub struct Bytes(usize); - -pub trait SizeUnit: Clone + Copy + PartialEq + Eq + PartialOrd + Ord { - fn num_bytes(&self) -> usize; -} - -impl SizeUnit for Bytes { - fn num_bytes(&self) -> usize { - self.0 - } -} - -impl From for Size { - fn from(x: usize) -> Self { - Size(Bytes(x)) - } -} - -/// a virtual register -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum Reg { - Virtual(usize), -} - -impl std::fmt::Display for Reg { - fn fmt( - &self, - f: &mut std::fmt::Formatter<'_>, - ) -> std::fmt::Result { - match self { - Reg::Virtual(a) => write!(f, "v{a}"), - } - } -}