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 aaf278b..92d92fd 100644 --- a/petr-lower/src/lib.rs +++ b/petr-lower/src/lib.rs @@ -14,7 +14,6 @@ trait LoweredFunction { returns: Option, ) -> Self; } - trait Lowerer { type LoweredExpr; type Error; @@ -58,14 +57,33 @@ struct LoweredFunction { body: Vec, returns: Option, } +||||||| 05bc7b9 +======= + fn lower_expr( + &mut self, + expr: &TypedExpr, + ) -> Result; +} +>>>>>>> 4826e6a8fd5b0098b726e187b7400d8a799e4856 struct JsFunction { +<<<<<<< HEAD name: String, args: Vec, body: Vec, returns: Option, +||||||| 05bc7b9 + name: String, + args: Vec, + body: Vec, +======= + name: String, + args: Vec, + body: Vec, +>>>>>>> 4826e6a8fd5b0098b726e187b7400d8a799e4856 } +<<<<<<< HEAD enum JsExpr { Literal(JsLiteral), List(Vec), @@ -96,13 +114,40 @@ enum JsLiteral { Integer(i64), Boolean(bool), String(String), +||||||| 05bc7b9 +enum Js{ + Return(Box), + Assign(String, JsExpr), + Call(String, Vec), +======= +enum Js { + Return(Box), + Assign(String, Box), + Call(String, Vec), + Literal(JsLiteral), +} + +enum JsLiteral { + String(String), + Int(i64), + Float(f64), +>>>>>>> 4826e6a8fd5b0098b726e187b7400d8a799e4856 } /// Lowers Petr into Javascript. +<<<<<<< HEAD struct JsLowerer { functions: BTreeMap, +||||||| 05bc7b9 +struct JSLowerer { + functions: BTreeMap; +======= +struct JSLowerer { + functions: BTreeMap, +>>>>>>> 4826e6a8fd5b0098b726e187b7400d8a799e4856 } +<<<<<<< HEAD impl Lowerer for JsLowerer { type Error = (); type LoweredExpr = JsExpr; @@ -178,3 +223,39 @@ impl JsLowerer { } } } +||||||| 05bc7b9 +======= +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!(), + } + } +} +>>>>>>> 4826e6a8fd5b0098b726e187b7400d8a799e4856 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}"), - } - } -}