implement _f literal suffix as shortcut for NUM as f32

This commit is contained in:
2022-04-10 23:58:18 +02:00
parent ebc701e2f2
commit aac7bbd878
2 changed files with 31 additions and 5 deletions

View File

@@ -140,6 +140,20 @@ fn fold_expr(context: &Context, expr: &mut ast::Expression) {
(ast::UnaryOp::Negate, ast::Expr::F64Const(value)) => { (ast::UnaryOp::Negate, ast::Expr::F64Const(value)) => {
Some(ast::Expr::F64Const(-*value)) Some(ast::Expr::F64Const(-*value))
} }
(ast::UnaryOp::Negate, ast::Expr::Cast { value, type_ }) => {
if let ast::Expr::I32Const(v) = value.expr {
Some(ast::Expr::Cast {
value: Box::new(ast::Expression {
expr: ast::Expr::I32Const(-v),
span: value.span.clone(),
type_: value.type_,
}),
type_: *type_,
})
} else {
None
}
}
(ast::UnaryOp::Not, ast::Expr::I32Const(value)) => { (ast::UnaryOp::Not, ast::Expr::I32Const(value)) => {
Some(ast::Expr::I32Const((*value == 0) as i32)) Some(ast::Expr::I32Const((*value == 0) as i32))
} }

View File

@@ -79,6 +79,7 @@ enum Token {
Str(String), Str(String),
Int(i32), Int(i32),
Int64(i64), Int64(i64),
IntFloat(i32),
Float(String), Float(String),
Float64(String), Float64(String),
Op(String), Op(String),
@@ -107,6 +108,7 @@ impl fmt::Display for Token {
Token::Str(s) => write!(f, "{:?}", s), Token::Str(s) => write!(f, "{:?}", s),
Token::Int(v) => write!(f, "{}", v), Token::Int(v) => write!(f, "{}", v),
Token::Int64(v) => write!(f, "{}", v), Token::Int64(v) => write!(f, "{}", v),
Token::IntFloat(v) => write!(f, "{}_f", v),
Token::Float(v) => write!(f, "{}", v), Token::Float(v) => write!(f, "{}", v),
Token::Float64(v) => write!(f, "{}", v), Token::Float64(v) => write!(f, "{}", v),
Token::Op(s) => write!(f, "{}", s), Token::Op(s) => write!(f, "{}", s),
@@ -275,6 +277,11 @@ fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = LexerError> {
.then_ignore(just("i64")) .then_ignore(just("i64"))
.map(|n| Token::Int64(n as i64)); .map(|n| Token::Int64(n as i64));
let int_float = integer
.clone()
.then_ignore(just("_f"))
.map(|n| Token::IntFloat(n as i32));
let int = integer.try_map(|n, span| { let int = integer.try_map(|n, span| {
u32::try_from(n) u32::try_from(n)
.map(|n| Token::Int(n as i32)) .map(|n| Token::Int(n as i32))
@@ -334,6 +341,7 @@ fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = LexerError> {
let token = float let token = float
.or(float64) .or(float64)
.or(int64) .or(int64)
.or(int_float)
.or(int) .or(int)
.or(str_) .or(str_)
.or(op) .or(op)
@@ -349,10 +357,10 @@ fn lexer() -> impl Parser<char, Vec<(Token, Span)>, Error = LexerError> {
} }
fn map_token<O>( fn map_token<O>(
f: impl Fn(&Token) -> Option<O> + 'static + Clone, f: impl Fn(&Token, &Span) -> Option<O> + 'static + Clone,
) -> impl Parser<Token, O, Error = ScriptError> + Clone { ) -> impl Parser<Token, O, Error = ScriptError> + Clone {
filter_map(move |span, tok: Token| { filter_map(move |span, tok: Token| {
if let Some(output) = f(&tok) { if let Some(output) = f(&tok, &span) {
Ok(output) Ok(output)
} else { } else {
Err(ScriptError::expected_input_found( Err(ScriptError::expected_input_found(
@@ -376,12 +384,12 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
}) })
.labelled("identifier"); .labelled("identifier");
let integer = map_token(|tok| match tok { let integer = map_token(|tok, _| match tok {
Token::Int(v) => Some(*v), Token::Int(v) => Some(*v),
_ => None, _ => None,
}); });
let string = map_token(|tok| match tok { let string = map_token(|tok, _| match tok {
Token::Str(s) => Some(s.clone()), Token::Str(s) => Some(s.clone()),
_ => None, _ => None,
}); });
@@ -390,9 +398,13 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
let block = recursive(|block| { let block = recursive(|block| {
let mut block_expression = None; let mut block_expression = None;
let expression = recursive(|expression| { let expression = recursive(|expression| {
let val = map_token(|tok| match tok { let val = map_token(|tok, span| match tok {
Token::Int(v) => Some(ast::Expr::I32Const(*v)), Token::Int(v) => Some(ast::Expr::I32Const(*v)),
Token::Int64(v) => Some(ast::Expr::I64Const(*v)), Token::Int64(v) => Some(ast::Expr::I64Const(*v)),
Token::IntFloat(v) => Some(ast::Expr::Cast {
value: Box::new(ast::Expr::I32Const(*v).with_span(span.clone())),
type_: ast::Type::F32,
}),
Token::Float(v) => Some(ast::Expr::F32Const(v.parse().unwrap())), Token::Float(v) => Some(ast::Expr::F32Const(v.parse().unwrap())),
Token::Float64(v) => Some(ast::Expr::F64Const(v.parse().unwrap())), Token::Float64(v) => Some(ast::Expr::F64Const(v.parse().unwrap())),
_ => None, _ => None,