Skip to content

Commit 63afba6

Browse files
committed
improved number operations
1 parent f0bdeae commit 63afba6

12 files changed

Lines changed: 5646 additions & 1577 deletions

File tree

Cargo.lock

Lines changed: 67 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/vim9-gen/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ edition = "2021"
88
[dependencies]
99
lexer = { path = "../vim9-lexer", package = "vim9-lexer" }
1010
parser = { path = "../vim9-parser", package = "vim9-parser" }
11+
vimfuncs = { path = "../vimfuncs" }
1112

1213
anyhow = "1.0.62"
1314
stylua = "0.14.3"

crates/vim9-gen/src/lib.rs

Lines changed: 53 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -789,15 +789,14 @@ impl Generate for IfCommand {
789789
//
790790
// This would allow us to remove the NVIM9.bool condition (assuming the type
791791
// system is correct in vim9script)
792-
//
793-
// let condition = match guess_type_of_expr(state, &self.condition).inner {
794-
// Type::Bool => condition,
795-
// _ => format!("NVIM9.bool({condition})"),
796-
// };
792+
let condition = match guess_type_of_expr(state, &self.condition) {
793+
Type::Bool => condition,
794+
_ => format!("NVIM9.bool({condition})"),
795+
};
797796

798797
format!(
799798
r#"
800-
if NVIM9.bool({condition}) then
799+
if {condition} then
801800
{}
802801
{}
803802
{}
@@ -881,36 +880,65 @@ fn identifier_list(state: &mut State, unpacked: &UnpackIdentifier) -> String {
881880
.collect()
882881
}
883882

883+
fn vim_to_type(ret: &vimfuncs::FuncReturnType) -> Type {
884+
match ret {
885+
vimfuncs::FuncReturnType::Any => Type::Any,
886+
vimfuncs::FuncReturnType::Bool => Type::Bool,
887+
vimfuncs::FuncReturnType::Float => Type::Float,
888+
vimfuncs::FuncReturnType::Number => Type::Number,
889+
vimfuncs::FuncReturnType::NumberBool => Type::BoolOrNumber,
890+
vimfuncs::FuncReturnType::String => Type::String,
891+
// vimfuncs::FuncReturnType::Void => Type::Any,
892+
// vimfuncs::FuncReturnType::Dict(_) => Type,
893+
// vimfuncs::FuncReturnType::List(_) => todo!(),
894+
// vimfuncs::FuncReturnType::Func(_) => todo!(),
895+
_ => Type::Any,
896+
}
897+
}
898+
884899
fn guess_type_of_expr(state: &State, expr: &Expression) -> Type {
885900
match expr {
886901
Expression::Number(_) => Type::Number,
887902
Expression::String(_) => Type::String,
888903
Expression::Boolean(_) => Type::Bool,
889-
Expression::Call(c) => match c.name() {
890-
Some(ident) => match ident {
891-
// TODO: Use our very cool new generated stuff here
892-
Identifier::Raw(raw) => match raw.name.as_str() {
893-
"charcol" => Type::Number,
894-
_ => Type::Any,
895-
},
904+
Expression::Call(c) => {
905+
match c.name() {
906+
Some(ident) => {
907+
match ident {
908+
// TODO: Use our very cool new generated stuff here
909+
Identifier::Raw(raw) => {
910+
match vimfuncs::get_func_info(&raw.name) {
911+
Some(info) => vim_to_type(&info.return_type),
912+
_ => Type::Any,
913+
}
914+
}
915+
_ => Type::Any,
916+
}
917+
}
896918
_ => Type::Any,
897-
},
898-
_ => Type::Any,
899-
},
919+
}
920+
}
900921
Expression::Infix(infix) => {
901922
if infix.operator.is_comparison() {
902923
return Type::Bool;
903924
}
904925

926+
let left_ty = guess_type_of_expr(state, infix.left.as_ref());
927+
let right_ty = guess_type_of_expr(state, infix.right.as_ref());
928+
905929
if matches!(infix.operator, Operator::And | Operator::Or) {
906-
if guess_type_of_expr(state, infix.left.as_ref()) == Type::Bool
907-
&& guess_type_of_expr(state, infix.right.as_ref())
908-
== Type::Bool
909-
{
930+
if left_ty == Type::Bool && right_ty == Type::Bool {
910931
return Type::Bool;
911932
}
912933
}
913934

935+
if left_ty == Type::Number
936+
&& right_ty == Type::Number
937+
&& infix.operator.is_math()
938+
{
939+
return dbg!(Type::Number);
940+
}
941+
914942
Type::Any
915943
}
916944
Expression::Grouped(g) => guess_type_of_expr(state, g.expr.as_ref()),
@@ -1348,6 +1376,11 @@ impl Generate for InfixExpression {
13481376
if let Some(literal) = self.operator.literal() {
13491377
match ty {
13501378
Bool => return format!("{left} {literal} {right}",),
1379+
Number => {
1380+
if self.operator.is_math() {
1381+
return format!("{left} {literal} {right}");
1382+
}
1383+
}
13511384
_ => {}
13521385
}
13531386
}

crates/vim9-gen/testdata/output/busted_loops.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ describe("filename", function()
3535
for _, y in NVIM9.iter({ 1, 2, 3 }) do
3636
x = NVIM9.ops["Plus"](x, y)
3737

38-
if NVIM9.bool(y == 2) then
38+
if y == 2 then
3939
break
4040
end
4141
end
@@ -56,11 +56,11 @@ describe("filename", function()
5656
local body = function(_, y)
5757
x = NVIM9.ops["Plus"](x, y)
5858

59-
if NVIM9.bool(y == 2) then
59+
if y == 2 then
6060
return NVIM9.ITER_CONTINUE
6161
end
6262

63-
if NVIM9.bool(y == 3) then
63+
if y == 3 then
6464
return NVIM9.ITER_BREAK
6565
end
6666

@@ -90,7 +90,7 @@ describe("filename", function()
9090
local x = 0
9191

9292
local body = function(_, y)
93-
if NVIM9.bool(y == 2) then
93+
if y == 2 then
9494
return NVIM9.ITER_CONTINUE
9595
end
9696

@@ -124,11 +124,11 @@ describe("filename", function()
124124
local x = 0
125125

126126
local body = function(_, y)
127-
if NVIM9.bool(y == 2) then
127+
if y == 2 then
128128
return NVIM9.ITER_RETURN, 5
129129
end
130130

131-
if NVIM9.bool(y == 10) then
131+
if y == 10 then
132132
return NVIM9.ITER_CONTINUE
133133
end
134134

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
source: crates/vim9-gen/src/lib.rs
3-
assertion_line: 1361
4-
expression: "generate(contents, false)"
3+
assertion_line: 1586
4+
expression: "generate(contents, false).unwrap()"
55
---
66
local NVIM9 = require("vim9script")
77
local __VIM9_MODULE = {}
88
-- vim9script
99

10-
vim.g["my_var"] = NVIM9.ops["Plus"](1, 2)
10+
vim.g["my_var"] = 1 + 2
1111
print(vim.g["my_var"])
1212
return __VIM9_MODULE
1313

crates/vim9-gen/testdata/output/vim9_gen__test__cfilter.snap

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/vim9-gen/src/lib.rs
3-
assertion_line: 1553
3+
assertion_line: 1577
44
expression: "generate(contents, false).unwrap()"
55
---
66
local NVIM9 = require("vim9script")
@@ -83,21 +83,21 @@ Qf_filter = function(qf, searchpat, bang)
8383

8484
firstchar = NVIM9.index(searchpat, 0)
8585
lastchar = NVIM9.slice(searchpat, -1, nil)
86-
if NVIM9.bool(firstchar == lastchar and (firstchar == "/" or firstchar == '"' or firstchar == "'")) then
86+
if firstchar == lastchar and (firstchar == "/" or firstchar == '"' or firstchar == "'") then
8787
pat = NVIM9.slice(searchpat, 1, -2)
88-
if NVIM9.bool(pat == "") then
88+
if pat == "" then
8989
-- # Use the last search pattern
9090
pat = vim.fn.getreg("/")
9191
end
9292
else
9393
pat = searchpat
9494
end
9595

96-
if NVIM9.bool(pat == "") then
96+
if pat == "" then
9797
return
9898
end
9999

100-
if NVIM9.bool(bang == "!") then
100+
if bang == "!" then
101101
Cond = function(_, val)
102102
return NVIM9.ops["NotRegexpMatches"](val["text"], pat)
103103
and NVIM9.ops["NotRegexpMatches"](NVIM9.fn["bufname"](val["bufnr"]), pat)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
---
22
source: crates/vim9-gen/src/lib.rs
3-
assertion_line: 1359
4-
expression: "generate(contents, false)"
3+
assertion_line: 1584
4+
expression: "generate(contents, false).unwrap()"
55
---
66
local NVIM9 = require("vim9script")
77
local __VIM9_MODULE = {}
88
-- vim9script
99

10-
local x = NVIM9.ops["Plus"](1, 2)
10+
local x = 1 + 2
1111
print(x)
1212
return __VIM9_MODULE
1313

crates/vim9-parser/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,11 @@ impl Operator {
13311331
)
13321332
}
13331333

1334+
pub fn is_math(&self) -> bool {
1335+
use Operator::*;
1336+
matches!(self, Plus | Minus | Multiply | Divide)
1337+
}
1338+
13341339
pub fn literal(&self) -> Option<&'static str> {
13351340
Some(match self {
13361341
Operator::Plus => "+",

crates/vimfuncs/Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ edition = "2021"
66
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
77

88
[dependencies]
9+
phf = "0.11.1"
910

10-
[[bin]]
11-
name = "main"
12-
path = "src/main.rs"
11+
[build-dependencies]
12+
anyhow = "1.0.66"
13+
phf_codegen = "0.11.1"

0 commit comments

Comments
 (0)