From 8ee8c2ccca91ee221047113e479089156609875a Mon Sep 17 00:00:00 2001 From: Vlamonster Date: Wed, 6 Dec 2023 00:36:11 +0100 Subject: [PATCH] Make integer literals generic. --- compiler/src/passes/atomize/mod.rs | 6 +-- .../src/passes/explicate/explicate_assign.rs | 5 +- .../src/passes/explicate/explicate_pred.rs | 9 ++-- compiler/src/passes/parse/grammar.lalrpop | 10 ++-- compiler/src/passes/parse/mod.rs | 10 ++-- compiler/src/passes/parse/types.rs | 6 +-- compiler/src/passes/reveal/mod.rs | 6 +-- compiler/src/passes/select/select.rs | 52 +++++++++---------- compiler/src/passes/validate/constrain/lit.rs | 22 ++++---- compiler/src/passes/validate/mod.rs | 18 ++----- compiler/src/passes/validate/partial_type.rs | 4 +- compiler/src/passes/validate/resolve.rs | 29 +++++------ compiler/src/utils/split_test.rs | 1 - compiler/tests/integration.rs | 1 - 14 files changed, 81 insertions(+), 98 deletions(-) diff --git a/compiler/src/passes/atomize/mod.rs b/compiler/src/passes/atomize/mod.rs index 0b811ac..fa28dc3 100644 --- a/compiler/src/passes/atomize/mod.rs +++ b/compiler/src/passes/atomize/mod.rs @@ -2,9 +2,9 @@ pub mod atomize; mod display; use crate::passes::parse::types::Type; -use crate::passes::parse::{BinaryOp, Def, Typed, UnaryOp}; +use crate::passes::parse::{BinaryOp, Def, Lit, Typed, UnaryOp}; use crate::passes::select::InstrSelected; -use crate::passes::validate::TLit; +use crate::passes::validate::Int; use crate::utils::gen_sym::UniqueSym; use derive_more::Display; use itertools::Itertools; @@ -81,7 +81,7 @@ pub enum AExpr<'p> { #[derive(Copy, Clone, Display)] pub enum Atom<'p> { - Val { val: TLit }, + Val { val: Lit }, Var { sym: UniqueSym<'p> }, } diff --git a/compiler/src/passes/explicate/explicate_assign.rs b/compiler/src/passes/explicate/explicate_assign.rs index 79d3499..30ce4f0 100644 --- a/compiler/src/passes/explicate/explicate_assign.rs +++ b/compiler/src/passes/explicate/explicate_assign.rs @@ -2,8 +2,7 @@ use crate::passes::atomize::{AExpr, Atom}; use crate::passes::explicate::explicate::Env; use crate::passes::explicate::{explicate_pred, ExprExplicated, TailExplicated}; -use crate::passes::parse::{Meta, Typed}; -use crate::passes::validate::TLit; +use crate::passes::parse::{Lit, Meta, Typed}; use crate::utils::gen_sym::{gen_sym, UniqueSym}; pub fn explicate_assign<'p>( @@ -119,7 +118,7 @@ pub fn explicate_assign<'p>( Meta { meta: bnd.meta, inner: AExpr::Atom { - atm: Atom::Val { val: TLit::Unit }, + atm: Atom::Val { val: Lit::Unit }, }, }, tail, diff --git a/compiler/src/passes/explicate/explicate_pred.rs b/compiler/src/passes/explicate/explicate_pred.rs index 08205da..15bea9f 100644 --- a/compiler/src/passes/explicate/explicate_pred.rs +++ b/compiler/src/passes/explicate/explicate_pred.rs @@ -3,8 +3,7 @@ use crate::passes::explicate::explicate::Env; use crate::passes::explicate::explicate_assign::explicate_assign; use crate::passes::explicate::{ExprExplicated, TailExplicated}; use crate::passes::parse::types::Type; -use crate::passes::parse::{BinaryOp, Meta, UnaryOp}; -use crate::passes::validate::TLit; +use crate::passes::parse::{BinaryOp, Lit, Meta, UnaryOp}; use crate::utils::gen_sym::gen_sym; pub fn explicate_pred<'p>( @@ -29,7 +28,7 @@ pub fn explicate_pred<'p>( exprs: [ Atom::Var { sym }, Atom::Val { - val: TLit::Bool(true), + val: Lit::Bool(true), }, ], }, @@ -38,7 +37,7 @@ pub fn explicate_pred<'p>( }, AExpr::Atom { atm: Atom::Val { - val: TLit::Bool(val), + val: Lit::Bool(val), }, .. } => { @@ -179,7 +178,7 @@ pub fn explicate_pred<'p>( AExpr::FunRef { .. } | AExpr::Atom { atm: Atom::Val { - val: TLit::Int { .. } | TLit::Unit, + val: Lit::Int { .. } | Lit::Unit, }, .. } diff --git a/compiler/src/passes/parse/grammar.lalrpop b/compiler/src/passes/parse/grammar.lalrpop index a9c1384..9649a36 100644 --- a/compiler/src/passes/parse/grammar.lalrpop +++ b/compiler/src/passes/parse/grammar.lalrpop @@ -1,5 +1,5 @@ use crate::passes::parse::{ - BinaryOp, DefParsed, ExprParsed, InstrParsed, Lit, Meta, Param, PrgParsed, Spanned, Type, TypeDef, UnaryOp, types::Int, + BinaryOp, DefParsed, ExprParsed, InstrParsed, Lit, Meta, Param, PrgParsed, Spanned, Type, TypeDef, UnaryOp, types::IntType, }; use crate::passes::select::{VarArg, Reg, Imm}; use functor_derive::Functor; @@ -159,8 +159,8 @@ Param: Param> = { } Type: Type> = { - "I64" => Type::Int(Int::I64), - "U64" => Type::Int(Int::I64), + "I64" => Type::Int(IntType::I64), + "U64" => Type::Int(IntType::U64), "Bool" => Type::Bool, "Unit" => Type::Unit, "Never" => Type::Never, @@ -336,9 +336,7 @@ ExprCall: ExprParsed<'input> = { ExprAtom: ExprParsed<'input> = { => ExprParsed::Lit { - val: Lit::Int { - val, - }, + val: Lit::Int(val), }, => ExprParsed::Lit { val: Lit::Bool(val) }, "unit" => ExprParsed::Lit { val: Lit::Unit }, diff --git a/compiler/src/passes/parse/mod.rs b/compiler/src/passes/parse/mod.rs index 19a17a1..4af7236 100644 --- a/compiler/src/passes/parse/mod.rs +++ b/compiler/src/passes/parse/mod.rs @@ -50,7 +50,7 @@ pub enum Def { } pub type DefParsed<'p> = Def, Spanned<&'p str>, Spanned>>; -pub type ExprParsed<'p> = Expr, Spanned<&'p str>, Lit<'p>, Span>; +pub type ExprParsed<'p> = Expr, Spanned<&'p str>, Lit<&'p str>, Span>; pub type InstrParsed<'p> = Instr>, Spanned<&'p str>>; #[derive(Clone, Debug)] @@ -331,11 +331,11 @@ pub enum BinaryOp { } /// A literal value. -#[derive(Display)] -pub enum Lit<'p> { +#[derive(Display, Debug, Copy, Clone)] +pub enum Lit { /// Integer literal, representing a signed 64-bit number. - #[display(fmt = "{val}")] - Int { val: &'p str }, + #[display(fmt = "{_0}")] + Int(Int), /// Boolean literal, representing a value of *true* or *false*. #[display(fmt = "{}", r#"if *_0 { "true" } else { "false" }"#)] Bool(bool), diff --git a/compiler/src/passes/parse/types.rs b/compiler/src/passes/parse/types.rs index 50c3cd1..c78ad5f 100644 --- a/compiler/src/passes/parse/types.rs +++ b/compiler/src/passes/parse/types.rs @@ -6,7 +6,7 @@ use std::fmt::Display; #[display(bound = "A: Display")] pub enum Type { #[display(fmt = "{_0}")] - Int(Int), + Int(IntType), #[display(fmt = "Bool")] Bool, #[display(fmt = "Unit")] @@ -23,8 +23,8 @@ pub enum Type { } /// Integer types -#[derive(Debug, Clone, Display, Eq, PartialEq)] -pub enum Int { +#[derive(Display, Debug, Copy, Clone, Eq, PartialEq)] +pub enum IntType { I8, U8, I16, diff --git a/compiler/src/passes/reveal/mod.rs b/compiler/src/passes/reveal/mod.rs index 448691e..58de654 100644 --- a/compiler/src/passes/reveal/mod.rs +++ b/compiler/src/passes/reveal/mod.rs @@ -1,9 +1,9 @@ mod display; pub mod reveal; -use crate::passes::parse::{BinaryOp, Def, Typed, UnaryOp}; +use crate::passes::parse::{BinaryOp, Def, Lit, Typed, UnaryOp}; use crate::passes::select::InstrSelected; -use crate::passes::validate::TLit; +use crate::passes::validate::Int; use crate::utils::gen_sym::UniqueSym; use derive_more::Display; use itertools::Itertools; @@ -20,7 +20,7 @@ pub type DefRevealed<'p> = Def, &'p str, Typed<'p, RExpr<'p>>>; pub enum RExpr<'p> { Lit { - val: TLit, + val: Lit, }, Var { sym: UniqueSym<'p>, diff --git a/compiler/src/passes/select/select.rs b/compiler/src/passes/select/select.rs index 3dbea9b..8b3a7ed 100644 --- a/compiler/src/passes/select/select.rs +++ b/compiler/src/passes/select/select.rs @@ -1,12 +1,12 @@ use crate::passes::atomize::Atom; use crate::passes::eliminate::{ExprEliminated, FunEliminated, PrgEliminated, TailEliminated}; use crate::passes::parse::types::Type; -use crate::passes::parse::{BinaryOp, Meta, UnaryOp}; +use crate::passes::parse::{BinaryOp, Lit, Meta, UnaryOp}; use crate::passes::select::{ Block, Cnd, FunSelected, InstrSelected, VarArg, X86Selected, CALLEE_SAVED_NO_STACK, CALLER_SAVED, }; -use crate::passes::validate::{TInt, TLit}; +use crate::passes::validate::Int; use crate::utils::gen_sym::{gen_sym, UniqueSym}; use crate::*; use std::collections::HashMap; @@ -258,20 +258,20 @@ fn select_atom(expr: Atom<'_>) -> VarArg> { match expr { Atom::Val { val } => { match val { - TLit::Int(int) => { + Lit::Int(int) => { match int { - TInt::I8(_) => todo!(), - TInt::U8(_) => todo!(), - TInt::I16(_) => todo!(), - TInt::U16(_) => todo!(), - TInt::I32(_) => todo!(), - TInt::U32(_) => todo!(), - TInt::I64(int) => imm32!(int as i32), // not correct yet - TInt::U64(_) => todo!(), + Int::I8(_) => todo!(), + Int::U8(_) => todo!(), + Int::I16(_) => todo!(), + Int::U16(_) => todo!(), + Int::I32(_) => todo!(), + Int::U32(_) => todo!(), + Int::I64(int) => imm32!(int as i32), // not correct yet + Int::U64(_) => todo!(), } } - TLit::Bool(bool) => imm32!(bool as i32), // todo: can be smaller - TLit::Unit => imm32!(0), // todo: can be smaller + Lit::Bool(bool) => imm32!(bool as i32), // todo: can be smaller + Lit::Unit => imm32!(0), // todo: can be smaller } } Atom::Var { sym } => var!(sym), @@ -290,21 +290,21 @@ fn select_cmp(op: BinaryOp) -> Cnd { } } -impl From for u32 { - fn from(value: TLit) -> Self { +impl From> for u32 { + fn from(value: Lit) -> Self { match value { - TLit::Int(int) => match int { - TInt::I8(int) => int as u32, - TInt::U8(int) => int as u32, - TInt::I16(int) => int as u32, - TInt::U16(int) => int as u32, - TInt::I32(int) => int as u32, - TInt::U32(int) => int, - TInt::I64(int) => int as u32, - TInt::U64(int) => int as u32, + Lit::Int(int) => match int { + Int::I8(int) => int as u32, + Int::U8(int) => int as u32, + Int::I16(int) => int as u32, + Int::U16(int) => int as u32, + Int::I32(int) => int as u32, + Int::U32(int) => int, + Int::I64(int) => int as u32, + Int::U64(int) => int as u32, }, - TLit::Bool(bool) => bool as u32, - TLit::Unit => 0, + Lit::Bool(bool) => bool as u32, + Lit::Unit => 0, } } } diff --git a/compiler/src/passes/validate/constrain/lit.rs b/compiler/src/passes/validate/constrain/lit.rs index 95837f2..f831a6d 100644 --- a/compiler/src/passes/validate/constrain/lit.rs +++ b/compiler/src/passes/validate/constrain/lit.rs @@ -1,4 +1,4 @@ -use crate::passes::parse::types::Int; +use crate::passes::parse::types::IntType; use crate::passes::parse::{Constrained, Lit, Span}; use crate::passes::validate::constrain::uncover_globals::Env; use crate::passes::validate::error::TypeError; @@ -8,21 +8,21 @@ use crate::passes::validate::{ExprConstrained, MetaConstrained}; pub fn constrain_lit<'p>( env: &mut Env<'_, 'p>, span: Span, - val: Lit<'p>, + val: Lit<&'p str>, ) -> Result>, TypeError> { // Get the type of the literal. let typ = match &val { - Lit::Int { val } => match val.rfind(&['i', 'u']) { + Lit::Int(val) => match val.rfind(&['i', 'u']) { Some(suffix) => { let int = match &val[suffix..] { - "i8" => Int::I64, - "u8" => Int::U64, - "i16" => Int::I64, - "u16" => Int::U64, - "i32" => Int::I64, - "u32" => Int::U64, - "i64" => Int::I64, - "u64" => Int::U64, + "i8" => IntType::I64, + "u8" => IntType::U64, + "i16" => IntType::I64, + "u16" => IntType::U64, + "i32" => IntType::I64, + "u32" => IntType::U64, + "i64" => IntType::I64, + "u64" => IntType::U64, _ => unreachable!(), }; PartialType::Int(int) diff --git a/compiler/src/passes/validate/mod.rs b/compiler/src/passes/validate/mod.rs index a261b80..e560b5d 100644 --- a/compiler/src/passes/validate/mod.rs +++ b/compiler/src/passes/validate/mod.rs @@ -32,16 +32,16 @@ pub struct PrgConstrained<'p> { } pub type DefValidated<'p> = Def, &'p str, Typed<'p, ExprValidated<'p>>>; -pub type ExprValidated<'p> = Expr, &'p str, TLit, Type>>; +pub type ExprValidated<'p> = Expr, &'p str, Lit, Type>>; pub type DefConstrained<'p> = Def>, Spanned<&'p str>, Constrained>>; pub type ExprConstrained<'p> = - Expr>, Spanned<&'p str>, Lit<'p>, MetaConstrained>; + Expr>, Spanned<&'p str>, Lit<&'p str>, MetaConstrained>; pub type DefUniquified<'p> = Def>, Spanned<&'p str>, Spanned>>; -pub type ExprUniquified<'p> = Expr>, Spanned<&'p str>, Lit<'p>, Span>; +pub type ExprUniquified<'p> = Expr>, Spanned<&'p str>, Lit<&'p str>, Span>; pub type InstrUniquified<'p> = Instr>>, Spanned>>; pub struct MetaConstrained { @@ -50,17 +50,7 @@ pub struct MetaConstrained { } #[derive(Copy, Clone, Debug, PartialEq, Display)] -pub enum TLit { - #[display(fmt = "{_0}")] - Int(TInt), - #[display(fmt = "{}", r#"if *_0 { "true" } else { "false" }"#)] - Bool(bool), - #[display(fmt = "unit")] - Unit, -} - -#[derive(Copy, Clone, Debug, PartialEq, Display)] -pub enum TInt { +pub enum Int { I8(i8), U8(u8), I16(i16), diff --git a/compiler/src/passes/validate/partial_type.rs b/compiler/src/passes/validate/partial_type.rs index a191237..b4dd3a8 100644 --- a/compiler/src/passes/validate/partial_type.rs +++ b/compiler/src/passes/validate/partial_type.rs @@ -1,11 +1,11 @@ -use crate::passes::parse::types::Int; +use crate::passes::parse::types::IntType; use crate::utils::gen_sym::UniqueSym; use crate::utils::union_find::{UnionFind, UnionIndex}; use itertools::Itertools; #[derive(Debug, Clone)] pub enum PartialType<'p> { - Int(Int), + Int(IntType), IntAmbiguous, Bool, Unit, diff --git a/compiler/src/passes/validate/resolve.rs b/compiler/src/passes/validate/resolve.rs index 218b292..160a244 100644 --- a/compiler/src/passes/validate/resolve.rs +++ b/compiler/src/passes/validate/resolve.rs @@ -1,11 +1,10 @@ -use crate::passes::parse::types::{Int, Type}; +use crate::passes::parse::types::{IntType, Type}; use crate::passes::parse::{Constrained, Expr, Lit, Meta, Param, Span, Spanned, TypeDef, Typed}; use crate::passes::select::{Instr, InstrSelected, VarArg}; use crate::passes::validate::error::TypeError; use crate::passes::validate::partial_type::PartialType; use crate::passes::validate::{ - DefConstrained, DefValidated, ExprConstrained, ExprValidated, PrgConstrained, PrgValidated, - TInt, TLit, + DefConstrained, DefValidated, ExprConstrained, ExprValidated, Int, PrgConstrained, PrgValidated, }; use crate::utils::gen_sym::UniqueSym; use crate::utils::union_find::{UnionFind, UnionIndex}; @@ -165,42 +164,42 @@ fn resolve_expr<'p>( let expr = match expr.inner { Expr::Lit { val } => { let val = match val { - Lit::Int { val, .. } => match &typ { + Lit::Int(val) => match &typ { Some(typ) => { let int = match typ { Type::Int(int) => match int { - Int::I8 => todo!(), - Int::U8 => TInt::U8(resolve_int_lit( + IntType::I8 => todo!(), + IntType::U8 => Int::U8(resolve_int_lit( val, expr.meta.span, u8::from_str_radix, )?), - Int::I16 => TInt::I16(resolve_int_lit( + IntType::I16 => Int::I16(resolve_int_lit( val, expr.meta.span, i16::from_str_radix, )?), - Int::U16 => TInt::U16(resolve_int_lit( + IntType::U16 => Int::U16(resolve_int_lit( val, expr.meta.span, u16::from_str_radix, )?), - Int::I32 => TInt::I32(resolve_int_lit( + IntType::I32 => Int::I32(resolve_int_lit( val, expr.meta.span, i32::from_str_radix, )?), - Int::U32 => TInt::U32(resolve_int_lit( + IntType::U32 => Int::U32(resolve_int_lit( val, expr.meta.span, u32::from_str_radix, )?), - Int::I64 => TInt::I64(resolve_int_lit( + IntType::I64 => Int::I64(resolve_int_lit( val, expr.meta.span, i64::from_str_radix, )?), - Int::U64 => TInt::U64(resolve_int_lit( + IntType::U64 => Int::U64(resolve_int_lit( val, expr.meta.span, u64::from_str_radix, @@ -208,7 +207,7 @@ fn resolve_expr<'p>( }, _ => unreachable!(), }; - TLit::Int(int) + Lit::Int(int) } None => { return Err(TypeError::IntegerAmbiguous { @@ -216,8 +215,8 @@ fn resolve_expr<'p>( }) } }, - Lit::Bool(bool) => TLit::Bool(bool), - Lit::Unit => TLit::Unit, + Lit::Bool(bool) => Lit::Bool(bool), + Lit::Unit => Lit::Unit, }; Expr::Lit { val } } diff --git a/compiler/src/utils/split_test.rs b/compiler/src/utils/split_test.rs index a05cfdc..18ef7fe 100644 --- a/compiler/src/utils/split_test.rs +++ b/compiler/src/utils/split_test.rs @@ -1,4 +1,3 @@ -use crate::passes::validate::TLit; use std::cell::OnceCell; /// Splits the inputs, expected outputs and expected return from the test. diff --git a/compiler/tests/integration.rs b/compiler/tests/integration.rs index 752093e..df1aa20 100644 --- a/compiler/tests/integration.rs +++ b/compiler/tests/integration.rs @@ -1,7 +1,6 @@ #![cfg(unix)] use compiler::passes::parse::parse::parse_program; -use compiler::passes::validate::TLit; use compiler::utils::split_test::{split_test, str_to_int}; use std::fs::OpenOptions; use std::io::{BufRead, Write};