rust: parsing of literals

This commit is contained in:
Alain Zscheile 2023-11-03 15:54:42 +01:00
parent 1f2329ab5f
commit 09580d4998
4 changed files with 91 additions and 11 deletions

View file

@ -14,13 +14,6 @@ pub enum TyLit {
SigInt(IntSize),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Layout {
pub size: u64,
// alignment = 2**align_exp
pub align_exp: u8,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Literal {
Ty(TyLit),
@ -28,6 +21,56 @@ pub enum Literal {
Natural(usize),
}
impl core::str::FromStr for Literal {
type Err = ();
fn from_str(s: &str) -> Result<Self, ()> {
use IntSize::Pow;
Ok(match s {
"Type" => Literal::Ty(TyLit::Type),
"Bool" => Literal::Ty(TyLit::Bool),
"String" => Literal::Ty(TyLit::String),
"IntSize" => Literal::Ty(TyLit::IntSize),
"S1" => Literal::IntSize(Pow(0)),
"S2" => Literal::IntSize(Pow(1)),
"S4" => Literal::IntSize(Pow(2)),
"S8" => Literal::IntSize(Pow(3)),
"S16" => Literal::IntSize(Pow(4)),
"S32" => Literal::IntSize(Pow(5)),
"S64" => Literal::IntSize(Pow(6)),
"S128" => Literal::IntSize(Pow(7)),
"S_size" => Literal::IntSize(IntSize::Isize),
"U1" => Literal::Ty(TyLit::UnsInt(Pow(0))),
"U2" => Literal::Ty(TyLit::UnsInt(Pow(1))),
"U4" => Literal::Ty(TyLit::UnsInt(Pow(2))),
"U8" => Literal::Ty(TyLit::UnsInt(Pow(3))),
"U16" => Literal::Ty(TyLit::UnsInt(Pow(4))),
"U32" => Literal::Ty(TyLit::UnsInt(Pow(5))),
"U64" => Literal::Ty(TyLit::UnsInt(Pow(6))),
"U128" => Literal::Ty(TyLit::UnsInt(Pow(7))),
"U_size" => Literal::Ty(TyLit::UnsInt(IntSize::Isize)),
"I2" => Literal::Ty(TyLit::SigInt(Pow(1))),
"I4" => Literal::Ty(TyLit::SigInt(Pow(2))),
"I8" => Literal::Ty(TyLit::SigInt(Pow(3))),
"I16" => Literal::Ty(TyLit::SigInt(Pow(4))),
"I32" => Literal::Ty(TyLit::SigInt(Pow(5))),
"I64" => Literal::Ty(TyLit::SigInt(Pow(6))),
"I128" => Literal::Ty(TyLit::SigInt(Pow(7))),
"I_size" => Literal::Ty(TyLit::SigInt(IntSize::Isize)),
_ => return Err(()),
})
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Layout {
pub size: u64,
// alignment = 2**align_exp
pub align_exp: u8,
}
impl Layout {
pub const fn max_size_for_align_exp(align_exp: u8) -> u64 {
let x = match 1u64.checked_shl(align_exp as u32) {
@ -87,6 +130,10 @@ pub const LAYOUT_I8: Layout = Layout {
align_exp: 0,
size: 1,
};
pub const LAYOUT_INTSIZE: Layout = Layout {
align_exp: 0,
size: 1,
};
pub const LAYOUT_I16: Layout = Layout {
align_exp: 1,
size: 2,

View file

@ -206,6 +206,7 @@ pub enum ErrorKind {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ErrorCtx {
Comment,
Literal,
Pattern,
Record,
Select,
@ -217,6 +218,7 @@ impl fmt::Display for ErrorCtx {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
ErrorCtx::Comment => "comment",
ErrorCtx::Literal => "literal",
ErrorCtx::Pattern => "pattern",
ErrorCtx::Record => "record",
ErrorCtx::Select => "selection",

View file

@ -1,2 +1,35 @@
pub use yanais_literal::{IntSize, TyLit, Literal};
/*
* SPDX-FileCopyrightText: 2023 Alain Zscheile <fogti+devel@ytrizja.de>
*
* SPDX-License-Identifier: Apache-2.0
*/
use crate::{lex, Env as ParseEnv, Error, ErrorCtx, EvEqSourceSpan, MaybeParse, ParseDefaultCtx};
pub use yanais_literal::{IntSize, Literal, TyLit};
impl ParseDefaultCtx for (EvEqSourceSpan, Literal) {
const DFL_CTX: ErrorCtx = ErrorCtx::Literal;
}
impl MaybeParse<Literal> for (EvEqSourceSpan, Literal) {
fn maybe_parse(env: &mut ParseEnv<'_, Literal>) -> Result<Option<Self>, Error> {
let mut nxtlxr = env.lxr.clone();
let lex::Token {
kind,
span: tok_span,
} = match nxtlxr.next().transpose()? {
None => return Ok(None),
Some(x) => x,
};
use lex::TokenKind as Tk;
Ok(match kind {
Tk::Kw(lit) => {
env.lxr = nxtlxr;
Some((tok_span, lit))
}
_ => None,
})
}
}

View file

@ -27,9 +27,7 @@ impl Pattern {
assert!(!x.is_empty());
1
}
Pattern::Record(rcd) => {
rcd.fields.iter().map(|(_, i)| i.alloc_slots()).sum()
}
Pattern::Record(rcd) => rcd.fields.iter().map(|(_, i)| i.alloc_slots()).sum(),
}
}
}