Skip to content

Commit f0bdeae

Browse files
committed
work on improving boolean semantics
1 parent 1f64c82 commit f0bdeae

7 files changed

Lines changed: 87 additions & 31 deletions

File tree

crates/vim9-gen/src/lib.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ impl Generate for DeclCommand {
475475
Some(ty) => match ty {
476476
Type::Any => "0",
477477
Type::Bool => "false",
478+
Type::BoolOrNumber => "false",
478479
Type::Number => "0",
479480
Type::Float => "0",
480481
Type::String => "''",
@@ -619,8 +620,7 @@ impl Generate for DefCommand {
619620
"#,
620621
)
621622
} else {
622-
let (signature, default_statements) =
623-
gen_signature(state, &self.args);
623+
let (signature, sig_statements) = gen_signature(state, &self.args);
624624

625625
let local = if state.is_top_level() || !self.name.is_valid_local() {
626626
""
@@ -633,9 +633,9 @@ impl Generate for DefCommand {
633633
format!(
634634
r#"
635635
{local} {name} = function({signature})
636-
local nvim9_deferred = {{}}
636+
{sig_statements}
637637
638-
{default_statements}
638+
local nvim9_deferred = {{}}
639639
local _, ret = pcall(function()
640640
{body}
641641
end)
@@ -663,7 +663,7 @@ impl Generate for DefCommand {
663663
format!(
664664
r#"
665665
{local} {name} = function({signature})
666-
{default_statements}
666+
{sig_statements}
667667
{body}
668668
end
669669
"#,
@@ -682,13 +682,27 @@ fn gen_signature(state: &mut State, args: &Signature) -> (String, String) {
682682
.join(", "),
683683
args.params
684684
.iter()
685-
.filter(|p| p.default_val.is_some())
685+
.filter(|p| {
686+
p.default_val.is_some()
687+
|| matches!(p.ty, Some(Type::BoolOrNumber))
688+
})
686689
.map(|p| {
687-
let name = p.name.gen(state);
688-
let default_val = p.default_val.clone().unwrap();
689-
let default_val = default_val.gen(state);
690+
// TODO: What about val=true defaults?
691+
match p.ty {
692+
Some(Type::BoolOrNumber) => {
693+
let name = p.name.gen(state);
694+
format!("{name} = not not {name}")
695+
}
696+
_ => {
697+
let name = p.name.gen(state);
698+
let default_val = p.default_val.clone().unwrap();
699+
let default_val = default_val.gen(state);
690700

691-
format!("{name} = vim.F.if_nil({name}, {default_val}, {name})")
701+
format!(
702+
"{name} = vim.F.if_nil({name}, {default_val}, {name})"
703+
)
704+
}
705+
}
692706
})
693707
.collect::<Vec<String>>()
694708
.join("\n"),

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ describe("filename", function()
3939

4040
MyDefer = function()
4141
local nvim9_deferred = {}
42-
4342
local _, ret = pcall(function()
4443
local x = {}
4544
table.insert(nvim9_deferred, 1, function()
@@ -66,7 +65,6 @@ describe("filename", function()
6665

6766
RangeDefer = function()
6867
local nvim9_deferred = {}
69-
7068
local _, ret = pcall(function()
7169
local x = {}
7270

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/vim9-gen/src/lib.rs
3-
assertion_line: 1542
3+
assertion_line: 1553
44
expression: "generate(contents, false).unwrap()"
55
---
66
local NVIM9 = require("vim9script")
@@ -26,6 +26,7 @@ local Qf_filter = nil
2626
-- #
2727

2828
Qf_filter = function(qf, searchpat, bang)
29+
qf = not not qf
2930
local Xgetlist = function() end
3031
local Xsetlist = function() end
3132
local cmd = ""

crates/vim9-parser/src/lib.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use anyhow::Result;
1111
use macros::parse_context;
1212
use once_cell::sync::OnceCell;
1313
use tracing_subscriber::util::SubscriberInitExt;
14+
use types::TypeOpts;
1415
use vim9_lexer::{Lexer, Span, Token, TokenKind};
1516
mod cmds;
1617
pub use cmds::{
@@ -201,7 +202,7 @@ impl DefCommand {
201202
args: Signature::parse(parser)?,
202203
ret: {
203204
if parser.front_kind() == TokenKind::SpacedColon {
204-
Some(Type::parse(parser)?)
205+
Some(Type::parse(parser, &TypeOpts { bool: Type::Bool })?)
205206
} else {
206207
None
207208
}
@@ -487,7 +488,12 @@ impl ForCommand {
487488
for_: parser.expect_identifier_with_text("for")?.into(),
488489
for_identifier: Identifier::parse(parser)?,
489490
for_type: if parser.front_kind() == TokenKind::SpacedColon {
490-
Some(Type::parse(parser)?)
491+
Some(Type::parse(
492+
parser,
493+
&TypeOpts {
494+
bool: Type::BoolOrNumber,
495+
},
496+
)?)
491497
} else {
492498
None
493499
},
@@ -739,7 +745,12 @@ impl Parameter {
739745

740746
let ty = if parser.peek_real_kind() == TokenKind::SpacedColon {
741747
parser.next_real_token();
742-
Some(Type::parse_in_expression(parser)?)
748+
Some(Type::parse_in_expression(
749+
parser,
750+
&TypeOpts {
751+
bool: Type::BoolOrNumber,
752+
},
753+
)?)
743754
} else {
744755
None
745756
};
@@ -1025,7 +1036,12 @@ impl Lambda {
10251036
args: Signature::parse(parser)?,
10261037
ret: {
10271038
if parser.front_kind() == TokenKind::SpacedColon {
1028-
Some(Type::parse(parser)?)
1039+
Some(Type::parse(
1040+
parser,
1041+
&TypeOpts {
1042+
bool: Type::BoolOrNumber,
1043+
},
1044+
)?)
10291045
} else {
10301046
None
10311047
}
@@ -1449,7 +1465,9 @@ impl VarCommand {
14491465
TokenKind::HeredocOperator => None,
14501466
TokenKind::EndOfLine => None,
14511467
TokenKind::EndOfFile => None,
1452-
TokenKind::SpacedColon => Some(Type::parse(parser)?),
1468+
TokenKind::SpacedColon => {
1469+
Some(Type::parse(parser, &TypeOpts { bool: Type::Bool })?)
1470+
}
14531471
_ => {
14541472
return Err(anyhow::anyhow!(
14551473
"invalid type and/or equal for var: {:?}",

crates/vim9-parser/src/types.rs

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,27 @@
11
use anyhow::Result;
2-
use vim9_lexer::{Token, TokenKind};
2+
use vim9_lexer::TokenKind;
33

44
use crate::{Literal, Parser, TokenMeta};
55

6+
pub struct TypeOpts {
7+
pub bool: Type,
8+
}
9+
610
#[derive(Debug, PartialEq, Clone)]
711
pub enum Type {
812
Any,
13+
14+
// TODO: Decide what to do with these.
15+
// It's possible we can just dismiss
16+
// BoolOrNumber, but i'm not 100% sure.
17+
//
18+
// The way we could do that would be to
19+
// just "not not" everything that comes from
20+
// vimland... but I feel like BoolOrNumber makes
21+
// that better by only doing it when we see a BoolOrNumber
922
Bool,
23+
BoolOrNumber,
24+
1025
Number,
1126
Float,
1227
String,
@@ -41,7 +56,11 @@ impl Type {
4156
matches!(k, TokenKind::GreaterThan | TokenKind::AngleRight)
4257
}
4358

44-
fn parse_inner(parser: &Parser, consume: bool) -> Result<Type> {
59+
fn parse_inner(
60+
parser: &Parser,
61+
consume: bool,
62+
opts: &TypeOpts,
63+
) -> Result<Type> {
4564
match parser.front_kind() {
4665
TokenKind::Identifier => {
4766
let literal: Literal = match consume {
@@ -52,7 +71,8 @@ impl Type {
5271

5372
Ok(match literal.token.text.as_str() {
5473
"any" => Type::Any,
55-
"bool" => Type::Bool,
74+
// "bool" => Type::BoolOrNumber,
75+
"bool" => opts.bool.clone(),
5676
"number" => Type::Number,
5777
"void" => Type::Void,
5878
"string" => Type::String,
@@ -64,7 +84,8 @@ impl Type {
6484

6585
Type::List {
6686
open: parser.expect_fn(Self::open, true)?.into(),
67-
inner: Type::parse_inner(parser, true)?.into(),
87+
inner: Type::parse_inner(parser, true, &opts)?
88+
.into(),
6889
close: parser
6990
.expect_fn(Self::close, consume)?
7091
.into(),
@@ -77,7 +98,8 @@ impl Type {
7798

7899
Type::Dict {
79100
open: parser.expect_fn(Self::open, true)?.into(),
80-
inner: Type::parse_inner(parser, true)?.into(),
101+
inner: Type::parse_inner(parser, true, &opts)?
102+
.into(),
81103
close: parser
82104
.expect_fn(Self::close, consume)?
83105
.into(),
@@ -93,13 +115,16 @@ impl Type {
93115
}
94116
}
95117

96-
pub fn parse_in_expression(parser: &Parser) -> Result<Type> {
118+
pub fn parse_in_expression(
119+
parser: &Parser,
120+
opts: &TypeOpts,
121+
) -> Result<Type> {
97122
parser.expect_token(TokenKind::SpacedColon)?;
98-
Self::parse_inner(parser, false)
123+
Self::parse_inner(parser, false, opts)
99124
}
100125

101-
pub fn parse(parser: &Parser) -> Result<Type> {
126+
pub fn parse(parser: &Parser, opts: &TypeOpts) -> Result<Type> {
102127
parser.expect_token(TokenKind::SpacedColon)?;
103-
Self::parse_inner(parser, true)
128+
Self::parse_inner(parser, true, opts)
104129
}
105130
}

crates/vim9-parser/testdata/output/vim9_parser__test__cfilter.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/vim9-parser/src/lib.rs
3-
assertion_line: 2877
3+
assertion_line: 2895
44
expression: snapshot_parsing(contents)
55
---
66
[
@@ -74,7 +74,7 @@ expression: snapshot_parsing(contents)
7474
Parameter {
7575
name: Raw(qf),
7676
ty: Some(
77-
Bool,
77+
BoolOrNumber,
7878
),
7979
equal: None,
8080
default_val: None,

crates/vim9-parser/testdata/output/vim9_parser__test__typed_params.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
source: crates/vim9-parser/src/lib.rs
3-
assertion_line: 2873
3+
assertion_line: 2891
44
expression: snapshot_parsing(contents)
55
---
66
[
@@ -23,7 +23,7 @@ expression: snapshot_parsing(contents)
2323
Parameter {
2424
name: Raw(qf),
2525
ty: Some(
26-
Bool,
26+
BoolOrNumber,
2727
),
2828
equal: None,
2929
default_val: None,

0 commit comments

Comments
 (0)