feat: support f-string

This commit is contained in:
Shunsuke Shibayama 2024-09-21 13:37:53 +09:00
parent 2fd2b37411
commit a1ffcf0a35
3 changed files with 51 additions and 0 deletions

View File

@ -1406,6 +1406,46 @@ impl ASTConverter {
let slice = self.convert_ident("slice".to_string(), loc);
slice.call(args).into()
}
py_ast::Expr::JoinedStr(string) => {
if string.values.is_empty() {
let loc = string.location();
let stringify = self.convert_ident("str".to_string(), loc);
return stringify.call(Args::empty()).into();
} else if string.values.len() == 1 {
let loc = string.location();
let mut values = string.values;
let expr = self.convert_expr(values.remove(0));
let stringify = self.convert_ident("str".to_string(), loc);
return stringify.call1(expr).into();
}
let mut values = vec![];
for value in string.values {
match value {
py_ast::Expr::Constant(cons) => {
let cons = self.convert_const(cons);
values.push(cons);
}
py_ast::Expr::FormattedValue(form) => {
let loc = form.location();
let expr = self.convert_expr(*form.value);
let stringify = self.convert_ident("str".to_string(), loc);
values.push(stringify.call1(expr).into());
}
_ => {}
}
}
let fst = values.remove(0);
values.into_iter().fold(fst, |acc, expr| {
let plus = Token::dummy(TokenKind::Plus, "+");
Expr::BinOp(BinOp::new(plus, acc, expr))
})
}
py_ast::Expr::FormattedValue(form) => {
let loc = form.location();
let expr = self.convert_expr(*form.value);
let stringify = self.convert_ident("str".to_string(), loc);
stringify.call1(expr).into()
}
_other => {
log!(err "unimplemented: {:?}", _other);
Expr::Dummy(Dummy::new(None, vec![]))
@ -1890,6 +1930,7 @@ impl ASTConverter {
fn convert_statement(&mut self, stmt: Stmt, dont_call_return: bool) -> Expr {
match stmt {
py_ast::Stmt::Expr(stmt) => self.convert_expr(*stmt.value),
// type-annotated assignment
py_ast::Stmt::AnnAssign(ann_assign) => {
let anot = self.convert_expr(*ann_assign.annotation.clone());
let t_spec = self.convert_type_spec(*ann_assign.annotation);

5
tests/literal.py Normal file
View File

@ -0,0 +1,5 @@
name = "John"
print(f"Hello, {name}!")
print(f"Hello, {nome}!") # ERR
print(f"Hello, {name + 1}!") # ERR

View File

@ -112,6 +112,11 @@ fn exec_list() -> Result<(), String> {
expect("tests/list.py", 0, 2)
}
#[test]
fn exec_literal() -> Result<(), String> {
expect("tests/literal.py", 0, 2)
}
#[test]
fn exec_narrowing() -> Result<(), String> {
expect("tests/narrowing.py", 0, 1)