tuple it up

This commit is contained in:
nora 2023-05-23 21:19:08 +02:00
parent 05c617f6de
commit dba217c18e
6 changed files with 43 additions and 79 deletions

View file

@ -4,7 +4,7 @@ mod typeck;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use parser::{ use parser::{
ast::{self, ExprBinary, IntTy, IntTyKind, IntSign}, ast::{self, ExprBinary, IntSign, IntTy, IntTyKind},
Span, Symbol, Span, Symbol,
}; };
use rustc_hash::{FxHashMap, FxHashSet}; use rustc_hash::{FxHashMap, FxHashSet};
@ -89,7 +89,7 @@ impl<'cx> LoweringCx<'cx> {
let layout = match *ty { let layout = match *ty {
TyKind::Void => Layout::size_align(0, 1), TyKind::Void => Layout::size_align(0, 1),
TyKind::Char => Layout::size_align(1, 1), TyKind::Char => Layout::size_align(1, 1),
TyKind::Int(int) => match int.kind { TyKind::Int(int) => match int.1 {
IntTyKind::Bool => Layout::size_align(1, 1), IntTyKind::Bool => Layout::size_align(1, 1),
IntTyKind::Char => Layout::size_align(1, 1), IntTyKind::Char => Layout::size_align(1, 1),
IntTyKind::Short => Layout::size_align(2, 2), IntTyKind::Short => Layout::size_align(2, 2),
@ -588,7 +588,7 @@ fn lower_func<'cx>(
impl<'cx> CommonTypes<'cx> { impl<'cx> CommonTypes<'cx> {
fn new(lcx: &LoweringCx<'cx>) -> Self { fn new(lcx: &LoweringCx<'cx>) -> Self {
let int = |sign, kind| lcx.intern_ty(TyKind::Int(IntTy { sign, kind })); let int = |sign, kind| lcx.intern_ty(TyKind::Int(IntTy(sign, kind)));
let int_pair = |kind| CommonInt { let int_pair = |kind| CommonInt {
signed: int(IntSign::Signed, kind), signed: int(IntSign::Signed, kind),
unsigned: int(IntSign::Unsigned, kind), unsigned: int(IntSign::Unsigned, kind),

View file

@ -49,11 +49,11 @@ impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> {
let lhs_prom_int = lhs_prom.unwrap_int(); let lhs_prom_int = lhs_prom.unwrap_int();
let rhs_prom_int = rhs_prom.unwrap_int(); let rhs_prom_int = rhs_prom.unwrap_int();
let lhs_sign = lhs_prom_int.sign; let lhs_sign = lhs_prom_int.0;
let rhs_sign = rhs_prom_int.sign; let rhs_sign = rhs_prom_int.0;
let lhs_kind = lhs_prom_int.kind; let lhs_kind = lhs_prom_int.1;
let rhs_kind = rhs_prom_int.kind; let rhs_kind = rhs_prom_int.1;
// If both operands have the same type, then no further conversion is needed. // If both operands have the same type, then no further conversion is needed.
let result = if lhs_prom == rhs_prom { let result = if lhs_prom == rhs_prom {
@ -61,7 +61,7 @@ impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> {
// Otherwise, if both operands have signed integer types or both have unsigned // Otherwise, if both operands have signed integer types or both have unsigned
// integer types, the operand with the type of lesser integer conversion rank is // integer types, the operand with the type of lesser integer conversion rank is
// converted to the type of the operand with greater rank. // converted to the type of the operand with greater rank.
} else if (lhs_sign.unsigned() && rhs_prom_int.sign.unsigned()) } else if (lhs_sign.unsigned() && rhs_prom_int.0.unsigned())
|| (lhs_sign.signed() && rhs_sign.signed()) || (lhs_sign.signed() && rhs_sign.signed())
{ {
if lhs_kind > rhs_kind { if lhs_kind > rhs_kind {
@ -109,10 +109,9 @@ impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> {
} else { } else {
rhs_kind rhs_kind
}; };
let ty = self.lcx.intern_ty(TyKind::Int(IntTy { let ty = self
kind, .lcx
sign: IntSign::Unsigned, .intern_ty(TyKind::Int(IntTy(IntSign::Unsigned, kind)));
}));
lhs_coerce.extend(self.coerce(lhs_prom, ty)?); lhs_coerce.extend(self.coerce(lhs_prom, ty)?);
ty ty
}; };
@ -127,36 +126,18 @@ impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> {
return Ok(smallvec![]); return Ok(smallvec![]);
} }
Ok(match (*from, *to) { Ok(match (*from, *to) {
( (TyKind::Char, TyKind::Int(IntTy(IntSign::Signed, _))) => {
TyKind::Char,
TyKind::Int(IntTy {
sign: IntSign::Signed,
..
}),
) => {
smallvec![(Coercion::SignExt, to)] smallvec![(Coercion::SignExt, to)]
} }
( (
TyKind::Int(IntTy { TyKind::Int(IntTy(IntSign::Signed, from_kind)),
sign: IntSign::Signed, TyKind::Int(IntTy(IntSign::Signed, to_kind)),
kind: from_kind,
}),
TyKind::Int(IntTy {
sign: IntSign::Signed,
kind: to_kind,
}),
) if from_kind < to_kind => { ) if from_kind < to_kind => {
smallvec![(Coercion::SignExt, to)] smallvec![(Coercion::SignExt, to)]
} }
( (
TyKind::Int(IntTy { TyKind::Int(IntTy(IntSign::Unsigned, from_kind)),
sign: IntSign::Unsigned, TyKind::Int(IntTy(IntSign::Unsigned, to_kind)),
kind: from_kind,
}),
TyKind::Int(IntTy {
sign: IntSign::Unsigned,
kind: to_kind,
}),
) if from_kind < to_kind => { ) if from_kind < to_kind => {
smallvec![(Coercion::ZeroExt, to)] smallvec![(Coercion::ZeroExt, to)]
} }
@ -168,7 +149,7 @@ impl<'a, 'cx> FnLoweringCtxt<'a, 'cx> {
fn promote(&self, ty: Ty<'cx>, span: Span) -> Result<Coercions<'cx>> { fn promote(&self, ty: Ty<'cx>, span: Span) -> Result<Coercions<'cx>> {
Ok(match *ty { Ok(match *ty {
TyKind::Char => smallvec![(Coercion::SignExt, self.types.int.signed)], TyKind::Char => smallvec![(Coercion::SignExt, self.types.int.signed)],
TyKind::Int(int) if int.kind < IntTyKind::Int => match int.sign { TyKind::Int(int) if int.1 < IntTyKind::Int => match int.0 {
IntSign::Signed => smallvec![(Coercion::SignExt, self.types.int.signed)], IntSign::Signed => smallvec![(Coercion::SignExt, self.types.int.signed)],
IntSign::Unsigned => { IntSign::Unsigned => {
smallvec![(Coercion::ZeroExt, self.types.int.unsigned)] smallvec![(Coercion::ZeroExt, self.types.int.unsigned)]

View file

@ -6,7 +6,7 @@ use std::{
use indexmap::IndexMap; use indexmap::IndexMap;
use parser::{ use parser::{
ast::{IntTy, IntTyKind, IntSign}, ast::{IntSign, IntTy, IntTyKind},
Symbol, Symbol,
}; };
@ -76,11 +76,11 @@ impl Display for Ty<'_> {
TyKind::Void => f.write_str("void"), TyKind::Void => f.write_str("void"),
TyKind::Char => f.write_str("char"), TyKind::Char => f.write_str("char"),
TyKind::Int(int) => { TyKind::Int(int) => {
match int.sign { match int.0 {
IntSign::Signed => f.write_str("signed "), IntSign::Signed => f.write_str("signed "),
IntSign::Unsigned => f.write_str("unsigned "), IntSign::Unsigned => f.write_str("unsigned "),
}?; }?;
match int.kind { match int.1 {
IntTyKind::Bool => f.write_str("_Bool"), IntTyKind::Bool => f.write_str("_Bool"),
IntTyKind::Char => f.write_str("char"), IntTyKind::Char => f.write_str("char"),
IntTyKind::Short => f.write_str("short"), IntTyKind::Short => f.write_str("short"),

View file

@ -169,10 +169,7 @@ pub enum IntTyKind {
} }
#[derive(Debug, DebugPls, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, DebugPls, Clone, Copy, PartialEq, Eq, Hash)]
pub struct IntTy { pub struct IntTy(pub IntSign, pub IntTyKind);
pub sign: IntSign,
pub kind: IntTyKind,
}
#[derive(Debug, DebugPls, Clone)] #[derive(Debug, DebugPls, Clone)]
pub enum TypeSpecifier { pub enum TypeSpecifier {

View file

@ -4,7 +4,7 @@ use peekmore::PeekMoreIterator;
use crate::{ use crate::{
ast::{ ast::{
Decl, DeclAttr, DeclSpec, Declarator, DirectDeclarator, ExternalDecl, FunctionDef, Decl, DeclAttr, DeclSpec, Declarator, DirectDeclarator, ExternalDecl, FunctionDef,
FunctionParamDecl, Ident, InitDecl, IntTy, IntTyKind, IntSign, NormalDecl, Stmt, FunctionParamDecl, Ident, InitDecl, IntSign, IntTy, IntTyKind, NormalDecl, Stmt,
TranslationUnit, TypeSpecifier, TranslationUnit, TypeSpecifier,
}, },
pre::Punctuator as P, pre::Punctuator as P,
@ -292,36 +292,29 @@ where
let ty = match token { let ty = match token {
Tok::Kw(Kw::Void) => TypeSpecifier::Void, Tok::Kw(Kw::Void) => TypeSpecifier::Void,
Tok::Kw(Kw::Char) => match signedness { Tok::Kw(Kw::Char) => match signedness {
Some(signedness) => TypeSpecifier::Integer(IntTy { Some(signedness) => TypeSpecifier::Integer(IntTy(signedness, IntTyKind::Char)),
sign: signedness,
kind: IntTyKind::Char,
}),
None => TypeSpecifier::Char, None => TypeSpecifier::Char,
}, },
Tok::Kw(Kw::Short) => { Tok::Kw(Kw::Short) => {
eat!(self, Tok::Kw(Kw::Int)); eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy { TypeSpecifier::Integer(IntTy(signedness.unwrap_or_default(), IntTyKind::Short))
sign: signedness.unwrap_or_default(), }
kind: IntTyKind::Short, Tok::Kw(Kw::Int) => {
}) TypeSpecifier::Integer(IntTy(signedness.unwrap_or_default(), IntTyKind::Int))
} }
Tok::Kw(Kw::Int) => TypeSpecifier::Integer(IntTy {
sign: signedness.unwrap_or_default(),
kind: IntTyKind::Int,
}),
Tok::Kw(Kw::Long) => { Tok::Kw(Kw::Long) => {
if eat!(self, Tok::Kw(Kw::Long)).is_some() { if eat!(self, Tok::Kw(Kw::Long)).is_some() {
eat!(self, Tok::Kw(Kw::Int)); eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy { TypeSpecifier::Integer(IntTy(
sign: signedness.unwrap_or_default(), signedness.unwrap_or_default(),
kind: IntTyKind::LongLong, IntTyKind::LongLong,
}) ))
} else { } else {
eat!(self, Tok::Kw(Kw::Int)); eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy { TypeSpecifier::Integer(IntTy(
sign: signedness.unwrap_or_default(), signedness.unwrap_or_default(),
kind: IntTyKind::Long, IntTyKind::Long,
}) ))
} }
} }
Tok::Kw(Kw::Signed) => { Tok::Kw(Kw::Signed) => {
@ -338,10 +331,7 @@ where
signedness = Some(IntSign::Signed); signedness = Some(IntSign::Signed);
continue; continue;
} }
TypeSpecifier::Integer(IntTy { TypeSpecifier::Integer(IntTy(IntSign::Signed, IntTyKind::Int))
sign: IntSign::Signed,
kind: IntTyKind::Int,
})
} }
Tok::Kw(Kw::Unsigned) => { Tok::Kw(Kw::Unsigned) => {
if signedness.is_some() { if signedness.is_some() {
@ -357,17 +347,13 @@ where
signedness = Some(IntSign::Unsigned); signedness = Some(IntSign::Unsigned);
continue; continue;
} }
TypeSpecifier::Integer(IntTy { TypeSpecifier::Integer(IntTy(IntSign::Unsigned, IntTyKind::Int))
sign: IntSign::Unsigned,
kind: IntTyKind::Int,
})
} }
Tok::Kw(Kw::Float) => TypeSpecifier::Float, Tok::Kw(Kw::Float) => TypeSpecifier::Float,
Tok::Kw(Kw::Double) => TypeSpecifier::Double, Tok::Kw(Kw::Double) => TypeSpecifier::Double,
Tok::Kw(Kw::Bool) => TypeSpecifier::Integer(IntTy { Tok::Kw(Kw::Bool) => {
sign: IntSign::Unsigned, TypeSpecifier::Integer(IntTy(IntSign::Unsigned, IntTyKind::Bool))
kind: IntTyKind::Bool, }
}),
Tok::Kw(Kw::Complex) => { Tok::Kw(Kw::Complex) => {
return Err(ParserError::new( return Err(ParserError::new(
span, span,

View file

@ -6,7 +6,7 @@ use crate::{
ast::{ ast::{
ArithOpKind, Atom, BinaryOp, ComparisonKind, Decl, DeclAttr, DeclSpec, Declarator, ArithOpKind, Atom, BinaryOp, ComparisonKind, Decl, DeclAttr, DeclSpec, Declarator,
DirectDeclarator, Expr, ExprBinary, ExprPostfix, ExprUnary, ExternalDecl, FunctionDef, DirectDeclarator, Expr, ExprBinary, ExprPostfix, ExprUnary, ExternalDecl, FunctionDef,
FunctionParamDecl, InitDecl, IntTyKind, IntSign, NormalDecl, PostfixOp, Stmt, FunctionParamDecl, InitDecl, IntSign, IntTyKind, NormalDecl, PostfixOp, Stmt,
TypeSpecifier, UnaryOp, TypeSpecifier, UnaryOp,
}, },
sym::Symbol, sym::Symbol,
@ -233,11 +233,11 @@ impl<W: Write> PrettyPrinter<W> {
TypeSpecifier::Char => self.string("char"), TypeSpecifier::Char => self.string("char"),
TypeSpecifier::Integer(int) => { TypeSpecifier::Integer(int) => {
// prefix the unsignedness if desired // prefix the unsignedness if desired
if let IntSign::Unsigned = int.sign { if let IntSign::Unsigned = int.0 {
self.string("unsigned ")?; self.string("unsigned ")?;
} }
match int.kind { match int.1 {
IntTyKind::Bool => self.string("_Bool"), IntTyKind::Bool => self.string("_Bool"),
IntTyKind::Char => self.string("char"), IntTyKind::Char => self.string("char"),
IntTyKind::Short => self.string("short"), IntTyKind::Short => self.string("short"),