mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 19:56:42 +01:00
implement _f literal suffix as shortcut for NUM as f32
This commit is contained in:
@@ -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))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user