mirror of
https://github.com/Noratrieb/uwucc.git
synced 2026-01-14 08:35:08 +01:00
tuple it up
This commit is contained in:
parent
05c617f6de
commit
dba217c18e
6 changed files with 43 additions and 79 deletions
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue