funny ints

This commit is contained in:
nora 2022-07-05 22:08:48 +02:00
parent c519241bd4
commit 8093f87fc3
9 changed files with 825 additions and 58 deletions

View file

@ -121,20 +121,40 @@ pub enum Stmt {
// --- Types and decls and garbage whatever
//
#[derive(Debug, DebugPls)]
pub enum IntTySignedness {
Signed,
Unsigned,
}
impl Default for IntTySignedness {
fn default() -> Self {
// C defaults to unsigned for integers.
Self::Signed
}
}
#[derive(Debug, DebugPls)]
pub enum IntTyKind {
Short,
Int,
Long,
LongLong,
}
#[derive(Debug, DebugPls)]
pub struct IntTy {
pub sign: IntTySignedness,
pub kind: IntTyKind,
}
#[derive(Debug, DebugPls)]
pub enum TypeSpecifier {
Void,
Char,
SChar,
UChar,
Short,
UShort,
Int,
UInt,
Long,
ULong,
LongLong,
ULongLong,
Integer(IntTy),
Float,
Double,
LongDouble,

View file

@ -4,7 +4,8 @@ use peekmore::PeekMoreIterator;
use crate::{
ast::{
Decl, DeclAttr, DeclSpec, Declarator, DirectDeclarator, ExternalDecl, FunctionDef,
FunctionParamDecl, Ident, InitDecl, NormalDecl, TypeSpecifier,
FunctionParamDecl, Ident, InitDecl, IntTy, IntTyKind, IntTySignedness, NormalDecl,
TypeSpecifier,
},
pre::Punctuator as Punct,
token::{Keyword as Kw, Token as Tok},
@ -282,27 +283,92 @@ where
}
fn type_specifier(&mut self) -> Result<Spanned<TypeSpecifier>> {
let (token, span) = self.next_t()?;
let ty = match token {
Tok::Kw(Kw::Void) => TypeSpecifier::Void,
Tok::Kw(Kw::Char) => TypeSpecifier::Char,
Tok::Kw(Kw::Short) => TypeSpecifier::Short,
Tok::Kw(Kw::Int) => TypeSpecifier::Int,
Tok::Kw(Kw::Long) => TypeSpecifier::Long,
Tok::Kw(Kw::Float) => TypeSpecifier::Float,
Tok::Kw(Kw::Double) => TypeSpecifier::Double,
Tok::Kw(Kw::Signed) => TypeSpecifier::Int,
Tok::Kw(Kw::Unsigned) => TypeSpecifier::UInt,
Tok::Kw(Kw::Bool) => TypeSpecifier::Bool,
Tok::Kw(Kw::Complex) => {
return Err(ParserError::new(
span,
"tf are you doing with complex numbers".to_string(),
))
}
tok => return Err(ParserError::new(span, format!("Invalid token: `{tok}`"))),
};
Ok((ty, span))
// todo: less shit code and better span handling
let mut signedness = None;
loop {
let (token, span) = self.next_t()?;
let ty = match token {
Tok::Kw(Kw::Void) => TypeSpecifier::Void,
Tok::Kw(Kw::Char) => match signedness {
Some(IntTySignedness::Signed) => TypeSpecifier::SChar,
Some(IntTySignedness::Unsigned) => TypeSpecifier::UChar,
None => TypeSpecifier::Char,
},
Tok::Kw(Kw::Short) => {
eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy {
sign: signedness.unwrap_or_default(),
kind: IntTyKind::Short,
})
}
Tok::Kw(Kw::Int) => TypeSpecifier::Integer(IntTy {
sign: signedness.unwrap_or_default(),
kind: IntTyKind::Int,
}),
Tok::Kw(Kw::Long) => {
if let Some(_) = eat!(self, Tok::Kw(Kw::Long)) {
eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy {
sign: signedness.unwrap_or_default(),
kind: IntTyKind::LongLong,
})
} else {
eat!(self, Tok::Kw(Kw::Int));
TypeSpecifier::Integer(IntTy {
sign: signedness.unwrap_or_default(),
kind: IntTyKind::Long,
})
}
}
Tok::Kw(Kw::Signed) => {
if signedness.is_some() {
return Err(ParserError::new(
span,
"cannot specify signedness twice".to_string(),
));
}
if let Ok((Tok::Kw(Kw::Char | Kw::Short| Kw::Int | Kw::Long), _)) = self.peek_t() {
// the signed is an integer qualifier
signedness = Some(IntTySignedness::Signed);
continue;
}
TypeSpecifier::Integer(IntTy {
sign: IntTySignedness::Signed,
kind: IntTyKind::Int,
})
}
Tok::Kw(Kw::Unsigned) => {
if signedness.is_some() {
return Err(ParserError::new(
span,
"cannot specify signedness twice".to_string(),
));
}
if let Ok((Tok::Kw(Kw::Char | Kw::Short| Kw::Int | Kw::Long), _)) = self.peek_t() {
// the unsigned is an integer qualifier
signedness = Some(IntTySignedness::Unsigned);
continue;
}
TypeSpecifier::Integer(IntTy {
sign: IntTySignedness::Unsigned,
kind: IntTyKind::Int,
})
}
Tok::Kw(Kw::Float) => TypeSpecifier::Float,
Tok::Kw(Kw::Double) => TypeSpecifier::Double,
Tok::Kw(Kw::Bool) => TypeSpecifier::Bool,
Tok::Kw(Kw::Complex) => {
return Err(ParserError::new(
span,
"tf are you doing with complex numbers".to_string(),
))
}
tok => return Err(ParserError::new(span, format!("Invalid token: `{tok}`"))),
};
break Ok((ty, span));
}
}
/// (6.7.6) declarator:

View file

@ -8,7 +8,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
FunctionDef(FunctionDef {
decl: Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
@ -21,7 +21,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
FunctionParamDecl {
decl_spec: (
DeclSpec {
ty: Long,
ty: Integer(IntTy { sign: Signed, kind: Long }),
attrs: "(empty)",
},
9..13,
@ -37,7 +37,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
FunctionParamDecl {
decl_spec: (
DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
19..22,

View file

@ -8,7 +8,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
FunctionDef(FunctionDef {
decl: Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "EXTERN | THREAD_LOCAL",
},
init_declarators: [

View file

@ -8,7 +8,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
@ -64,7 +64,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [

View file

@ -0,0 +1,637 @@
---
source: parser/src/parser/tests.rs
expression: "(parsed_pretty, pretty_printed_source)"
---
(
Ok([
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Char,
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("a", 24..25)),
pointer: false,
},
init: Some((Atom(Int(1)), 28..29)),
},
24..25,
),
],
}),
),
10..25,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: SChar,
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("b", 54..55)),
pointer: false,
},
init: Some((Atom(Int(2)), 58..59)),
},
54..55,
),
],
}),
),
31..55,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: UChar,
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("c", 84..85)),
pointer: false,
},
init: Some((Atom(Int(3)), 88..89)),
},
84..85,
),
],
}),
),
61..85,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Short }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("d", 115..116)),
pointer: false,
},
init: Some((Atom(Int(4)), 119..120)),
},
115..116,
),
],
}),
),
101..116,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Short }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("e", 145..146)),
pointer: false,
},
init: Some((Atom(Int(6)), 149..150)),
},
145..146,
),
],
}),
),
122..146,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Short }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("f", 175..176)),
pointer: false,
},
init: Some((Atom(Int(5)), 179..180)),
},
175..176,
),
],
}),
),
161..176,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Short }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("g", 205..206)),
pointer: false,
},
init: Some((Atom(Int(7)), 209..210)),
},
205..206,
),
],
}),
),
182..206,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: Short,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("h", 235..236)),
pointer: false,
},
init: Some((Atom(Int(8)), 239..240)),
},
235..236,
),
],
}),
),
212..236,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: Short,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("i", 265..266)),
pointer: false,
},
init: Some((Atom(Int(9)), 269..270)),
},
265..266,
),
],
}),
),
242..266,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("j", 296..297)),
pointer: false,
},
init: Some((Atom(Int(10)), 300..302)),
},
296..297,
),
],
}),
),
273..297,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("k", 327..328)),
pointer: false,
},
init: Some((Atom(Int(11)), 331..333)),
},
327..328,
),
],
}),
),
323..328,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("l", 358..359)),
pointer: false,
},
init: Some((Atom(Int(12)), 362..364)),
},
358..359,
),
],
}),
),
335..359,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Unsigned, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("m", 389..390)),
pointer: false,
},
init: Some((Atom(Int(13)), 393..395)),
},
389..390,
),
],
}),
),
366..390,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Unsigned, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("n", 420..421)),
pointer: false,
},
init: Some((Atom(Int(14)), 424..426)),
},
420..421,
),
],
}),
),
397..421,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Long }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("o", 452..453)),
pointer: false,
},
init: Some((Atom(Int(15)), 456..458)),
},
452..453,
),
],
}),
),
438..453,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Long }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("p", 483..484)),
pointer: false,
},
init: Some((Atom(Int(16)), 487..489)),
},
483..484,
),
],
}),
),
460..484,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Long }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("q", 514..515)),
pointer: false,
},
init: Some((Atom(Int(17)), 518..520)),
},
514..515,
),
],
}),
),
500..515,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy { sign: Signed, kind: Long }),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("r", 545..546)),
pointer: false,
},
init: Some((Atom(Int(18)), 549..551)),
},
545..546,
),
],
}),
),
522..546,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: Long,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("s", 576..577)),
pointer: false,
},
init: Some((Atom(Int(19)), 580..582)),
},
576..577,
),
],
}),
),
553..577,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: Long,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("t", 607..608)),
pointer: false,
},
init: Some((Atom(Int(20)), 611..613)),
},
607..608,
),
],
}),
),
584..608,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Signed,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("u", 639..640)),
pointer: false,
},
init: Some((Atom(Int(21)), 643..645)),
},
639..640,
),
],
}),
),
625..640,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Signed,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("v", 670..671)),
pointer: false,
},
init: Some((Atom(Int(22)), 674..676)),
},
670..671,
),
],
}),
),
647..671,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Signed,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("w", 701..702)),
pointer: false,
},
init: Some((Atom(Int(23)), 705..707)),
},
701..702,
),
],
}),
),
687..702,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Signed,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("x", 732..733)),
pointer: false,
},
init: Some((Atom(Int(24)), 736..738)),
},
732..733,
),
],
}),
),
709..733,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("y", 763..764)),
pointer: false,
},
init: Some((Atom(Int(25)), 767..769)),
},
763..764,
),
],
}),
),
740..764,
),
(
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Integer(IntTy {
sign: Unsigned,
kind: LongLong,
}),
attrs: "(empty)",
},
init_declarators: [
(
InitDecl {
declarator: Declarator {
decl: Ident(("z", 794..795)),
pointer: false,
},
init: Some((Atom(Int(26)), 798..800)),
},
794..795,
),
],
}),
),
771..795,
),
]),
"char a = 1;\nsigned char b = 2;\nunsigned char c = 3;\nshort d = 4;\nshort e = 6;\nshort f = 5;\nshort g = 7;\nunsigned short h = 8;\nunsigned short i = 9;\nint j = 10;\nint k = 11;\nint l = 12;\nunsigned int m = 13;\nunsigned int n = 14;\nlong o = 15;\nlong p = 16;\nlong q = 17;\nlong r = 18;\nunsigned long s = 19;\nunsigned long t = 20;\nlong long u = 21;\nlong long v = 22;\nlong long w = 23;\nlong long x = 24;\nunsigned long long y = 25;\nunsigned long long z = 26;\n",
)

View file

@ -8,7 +8,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
@ -38,7 +38,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [
@ -75,7 +75,7 @@ expression: "(parsed_pretty, pretty_printed_source)"
Decl(
Normal(NormalDecl {
decl_spec: DeclSpec {
ty: Int,
ty: Integer(IntTy { sign: Signed, kind: Int }),
attrs: "(empty)",
},
init_declarators: [

View file

@ -83,3 +83,41 @@ int z = (array[9]);
"#
);
}
#[test]
fn integer_types() {
parse_test!(
r#"
char a = 1;
signed char b = 2;
unsigned char c = 3;
short d = 4;
signed short e = 6;
short int f = 5;
signed short int g = 7;
unsigned short h = 8;
unsigned short int i = 9;
signed j = 10;
int k = 11;
signed int l = 12;
unsigned m = 13;
unsigned int n = 14;
long o = 15;
signed long p = 16;
long int q = 17;
signed long int r = 18;
unsigned long s = 19;
unsigned long int t = 20;
long long u = 21;
signed long long v = 22;
long long int w = 23;
signed long long int x = 24;
unsigned long long y = 25;
unsigned long long int z = 26;
"#
);
}

View file

@ -6,7 +6,8 @@ use crate::{
ast::{
ArithOpKind, Atom, BinaryOp, ComparisonKind, Decl, DeclAttr, DeclSpec, Declarator,
DirectDeclarator, Expr, ExprBinary, ExprUnary, ExternalDecl, FunctionDef,
FunctionParamDecl, InitDecl, NormalDecl, TypeSpecifier, UnaryOp,
FunctionParamDecl, InitDecl, IntTyKind, IntTySignedness, NormalDecl, TypeSpecifier,
UnaryOp,
},
Spanned,
};
@ -120,24 +121,29 @@ impl<W: Write> PrettyPrinter<W> {
}
fn type_specifier(&mut self, spec: &TypeSpecifier) -> Result {
self.string(match spec {
TypeSpecifier::Void => "void",
TypeSpecifier::Char => "char",
TypeSpecifier::SChar => "signed char",
TypeSpecifier::UChar => "unsigned char",
TypeSpecifier::Short => "short",
TypeSpecifier::UShort => "usigned short",
TypeSpecifier::Int => "int",
TypeSpecifier::UInt => "unsugned int",
TypeSpecifier::Long => "long",
TypeSpecifier::ULong => "unsigned long",
TypeSpecifier::LongLong => "long",
TypeSpecifier::ULongLong => "unsigned long long",
TypeSpecifier::Float => "float",
TypeSpecifier::Double => "double",
TypeSpecifier::LongDouble => "long double",
TypeSpecifier::Bool => "_Bool",
})
match spec {
TypeSpecifier::Void => self.string("void"),
TypeSpecifier::Char => self.string("char"),
TypeSpecifier::SChar => self.string("signed char"),
TypeSpecifier::UChar => self.string("unsigned char"),
TypeSpecifier::Integer(int) => {
// prefix the unsignedness if desired
if let IntTySignedness::Unsigned = int.sign {
self.string("unsigned ")?;
}
match int.kind {
IntTyKind::Short => self.string("short"),
IntTyKind::Int => self.string("int"),
IntTyKind::Long => self.string("long"),
IntTyKind::LongLong => self.string("long long"),
}
}
TypeSpecifier::Float => self.string("float"),
TypeSpecifier::Double => self.string("double"),
TypeSpecifier::LongDouble => self.string("long double"),
TypeSpecifier::Bool => self.string("_Bool"),
}
}
fn decl_attr(&mut self, attr: &DeclAttr) -> Result {