Skip to content

Commit

Permalink
add typing and bases for integer literals
Browse files Browse the repository at this point in the history
  • Loading branch information
Arav K. committed Dec 29, 2023
1 parent 5897942 commit 89cf6d8
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub enum Expr {
Cast(MappedType, ID<Self>),

/// An integer literal.
Int(BigInt),
Int(BigInt, Option<IntType>),

/// A vector literal.
Vec(SeqID<Self>),
Expand Down
26 changes: 24 additions & 2 deletions src/ast/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use core::iter;
use core::num::NonZeroU32;

use num_bigint::{BigInt, BigUint, Sign};
use pest::{self, iterators::{Pair, Pairs}};
use rustc_hash::FxHashMap;
use thiserror::Error;
Expand Down Expand Up @@ -363,10 +364,31 @@ impl Expr {
/// Parse an integer literal expression.
fn parse_int(
i: Pair<'_, Rule>,
_: &mut Parser,
p: &mut Parser,
) -> Result<Self, Error> {
assert_eq!(Rule::expr_int, i.as_rule());
Ok(Self::Int(i.as_str().parse().unwrap()))
let mut pairs = i.into_inner();
let sign = match pairs.next().unwrap().as_str() {
"+" => Sign::Plus,
"-" => Sign::Minus,
"" => Sign::Plus,
_ => unreachable!(),
};
let value = pairs.next().unwrap();
let radix = match value.as_rule() {
Rule::expr_int_bin => 2,
Rule::expr_int_oct => 8,
Rule::expr_int_dec => 10,
Rule::expr_int_hex => 16,
_ => unreachable!(),
};
let value = value.as_str().as_bytes();
let value = BigUint::parse_bytes(value, radix).unwrap();
let value = BigInt::from_biguint(sign, value);
let r#type = pairs.next()
.map(|i| IntType::parse(i, p))
.transpose()?;
Ok(Self::Int(value, r#type))
}

/// Parse a vector literal expression.
Expand Down
8 changes: 6 additions & 2 deletions src/ast/syn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,12 @@ impl Expr {
Ok(())
},

Expr::Int(ref val) => {
write!(w, "{}", val)
Expr::Int(ref val, it) => {
write!(w, "{}", val)?;
if let Some(it) = it {
write!(w, "{}", it)?;
}
Ok(())
},

Expr::Vec(src) => {
Expand Down
2 changes: 1 addition & 1 deletion src/hir/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ impl<'ast: 'tck, 'tck> Parser<'ast, 'tck> {
Node::BitCast(cop, src)
},

ast::Expr::Int(ref val) => {
ast::Expr::Int(ref val, _) => {
Node::Int(val.clone())
},

Expand Down
24 changes: 21 additions & 3 deletions src/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,25 @@ expr = { expr_unit ~ (op_bin ~ expr_unit)* }
/// An atomic expression.
atom = { expr_int | expr_vec | expr_cst | expr_var | expr_blk | "(" ~ expr ~ ")" }
/// An integer literal expression.
expr_int = @{ ASCII_DIGIT+ }
expr_int = ${
expr_int_sign
~ ( ("0b" ~ expr_int_bin)
| ("0o" ~ expr_int_oct)
| ("0x" ~ expr_int_hex)
| ("0d"? ~ expr_int_dec) )
~ type_int?
~ !ASCII_ALPHANUMERIC
}
/// The sign of an integer literal value.
expr_int_sign = @{ "-" | "+" | "" }
/// A binary integer literal value.
expr_int_bin = @{ ('0'..'1')+ }
/// An octal integer literal value.
expr_int_oct = @{ ('0'..'7')+ }
/// A decimal integer literal value.
expr_int_dec = @{ ('0'..'9')+ }
/// A hexadecimal integer literal value.
expr_int_hex = @{ ('0'..'9' | 'A'..'F' | 'a'..'f')+ }
/// A vector literal expression.
expr_vec = { "<" ~ (expr ~ ",")* ~ expr? ~ ">" }
/// A cast expression.
Expand All @@ -66,9 +84,9 @@ op_suf = { !ANY ~ ANY }
/// A binary (infix) operator.
op_bin = { op_add | op_sub | op_mul | op_div | op_rem
| op_and | op_ior | op_xor | op_shl | op_shr
| op_cat | op_ind | op_exp | op_red
| op_cat | op_ind | op_exp | op_red
| op_iseq | op_isne | op_isle | op_islt | op_isge | op_isgt
| op_cond | op_else
| op_cond | op_else
}
/// Addition.
op_add = { "+" }
Expand Down
5 changes: 3 additions & 2 deletions src/tck/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ impl<'ast> Storage<'ast> {
(dt, None)
},

ast::Expr::Int(_) => {
let res = Partial::Val(ScalarType::Int(Partial::Any));
ast::Expr::Int(_, it) => {
let res = it.map_or(Partial::Any, Partial::Val);
let res = Partial::Val(ScalarType::Int(res));
(Subtyping::infer(res, sup).ok()?
.with_part(Partial::Val(OptionPart::None))
.with_part(Partial::Val(VectorPart::None))
Expand Down

0 comments on commit 89cf6d8

Please sign in to comment.