Skip to content

Commit d790411

Browse files
committed
move everything to one lua file, for easy upstream
1 parent d5dc238 commit d790411

File tree

10 files changed

+521
-467
lines changed

10 files changed

+521
-467
lines changed

crates/vim9-gen/src/lib.rs

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,43 @@ use parser::{
2222
pub mod call_expr;
2323
mod test_harness;
2424

25+
#[derive(Debug, PartialEq)]
26+
pub enum ParserMode {
27+
Test,
28+
Autoload,
29+
Standalone,
30+
}
31+
32+
#[derive(Debug)]
33+
pub struct ParserOpts {
34+
pub mode: ParserMode,
35+
}
36+
2537
#[derive(Debug)]
2638
pub struct State {
27-
pub augroup: Option<Literal>,
28-
pub is_test: bool,
39+
pub opts: ParserOpts,
2940

3041
pub command_depth: i32,
3142
pub method_depth: i32,
3243

44+
// TODO: Consider moving augroup -> scopes
45+
// with a new scope type of augroup.
46+
//
47+
// That might be a nicer strategy (and mirrors
48+
// the same thing as we've done before).
49+
pub augroup: Option<Literal>,
50+
3351
// TODO: We could modify the state as we are generating code.
3452
// As we generate the code and notice certain identifiers are certain
3553
// types, we can use that to do *some* optimizations
3654
pub scopes: Vec<Scope>,
3755
}
3856

3957
impl State {
58+
fn is_test_mode(&self) -> bool {
59+
self.opts.mode == ParserMode::Test
60+
}
61+
4062
fn is_top_level(&self) -> bool {
4163
self.scopes.len() == 1
4264
}
@@ -76,6 +98,7 @@ impl State {
7698
.push_declaration(expr_1, expr_2)
7799
}
78100

101+
#[allow(unused)]
79102
fn lookup_declaration(&self, expr_1: &Expression) -> Option<Type> {
80103
match Scope::declaration_key(expr_1) {
81104
Some(key) => self
@@ -602,7 +625,7 @@ impl Generate for DefCommand {
602625
let (body, scope) =
603626
state.with_scope(ScopeKind::Function, |s| self.body.gen(s));
604627

605-
if state.is_test && name.starts_with("Test") {
628+
if state.opts.mode == ParserMode::Test && name.starts_with("Test") {
606629
assert!(scope.deferred == 0, "have not handled deferred in tests");
607630

608631
format!(
@@ -1006,6 +1029,17 @@ impl Generate for Identifier {
10061029

10071030
impl Generate for ScopedIdentifier {
10081031
fn gen(&self, state: &mut State) -> String {
1032+
if self.scope == VimScope::VimVar {
1033+
if let Identifier::Raw(raw) = self.accessor.as_ref() {
1034+
if raw.name == "version" {
1035+
// "lie" to vim9script code and say that we are
1036+
// version 9. This may need to be updated if
1037+
// vim updates their v:version variable
1038+
return "900".to_string();
1039+
}
1040+
}
1041+
}
1042+
10091043
let scope = match self.scope {
10101044
VimScope::Global => "vim.g",
10111045
VimScope::VimVar => "vim.v",
@@ -1419,13 +1453,13 @@ impl Generate for InfixExpression {
14191453
}
14201454
}
14211455

1422-
fn toplevel_id(s: &mut State, command: &ExCommand) -> Option<String> {
1456+
fn toplevel_ident(s: &mut State, command: &ExCommand) -> Option<String> {
14231457
match command {
14241458
ExCommand::Decl(decl) => Some(decl.name.gen(s)),
14251459
ExCommand::Def(def) => {
14261460
def.name.is_valid_local().then_some(def.name.gen(s))
14271461
}
1428-
ExCommand::ExportCommand(e) => toplevel_id(s, e.command.as_ref()),
1462+
ExCommand::ExportCommand(e) => toplevel_ident(s, e.command.as_ref()),
14291463
ExCommand::Heredoc(here) => Some(here.name.gen(s)),
14301464
// This might make sense, but I don't think it allows you to do this?
14311465
ExCommand::Var(_) => None,
@@ -1457,26 +1491,26 @@ fn toplevel_id(s: &mut State, command: &ExCommand) -> Option<String> {
14571491
}
14581492
}
14591493

1460-
pub fn eval(program: parser::Program, is_test: bool) -> String {
1494+
pub fn eval(program: parser::Program, opts: ParserOpts) -> String {
14611495
let mut state = State {
14621496
augroup: None,
14631497
command_depth: 0,
14641498
method_depth: 0,
14651499
scopes: vec![Scope::new(ScopeKind::TopLevel)],
1466-
is_test,
1500+
opts,
14671501
};
14681502

14691503
let mut output = String::new();
14701504
output += "local NVIM9 = require('vim9script')";
14711505
output += "local __VIM9_MODULE = {}\n";
14721506

1473-
if is_test {
1507+
if state.is_test_mode() {
14741508
output += "describe(\"filename\", function()\n"
14751509
}
14761510

14771511
// "hoist" top-level declaractions to top of program.
14781512
for command in program.commands.iter() {
1479-
if let Some(toplevel) = toplevel_id(&mut state, command) {
1513+
if let Some(toplevel) = toplevel_ident(&mut state, command) {
14801514
output += &format!("local {} = nil\n", toplevel);
14811515
}
14821516
}
@@ -1486,7 +1520,7 @@ pub fn eval(program: parser::Program, is_test: bool) -> String {
14861520
output += "\n";
14871521
}
14881522

1489-
if is_test {
1523+
if state.is_test_mode() {
14901524
output += "end)"
14911525
}
14921526

@@ -1497,13 +1531,13 @@ pub fn eval(program: parser::Program, is_test: bool) -> String {
14971531

14981532
pub fn generate(
14991533
contents: &str,
1500-
is_test: bool,
1534+
opts: ParserOpts,
15011535
) -> Result<String, (String, String)> {
15021536
let lexer = Lexer::new(contents);
15031537
let parser = new_parser(&lexer);
15041538
let program = parser.parse_program();
15051539

1506-
let result = eval(program, is_test);
1540+
let result = eval(program, opts);
15071541
// println!("{}", result);
15081542

15091543
let config = stylua_lib::Config::new()
@@ -1539,7 +1573,13 @@ mod test {
15391573
let mut settings = insta::Settings::clone_current();
15401574
settings.set_snapshot_path("../testdata/output/");
15411575
settings.bind(|| {
1542-
insta::assert_snapshot!(generate(contents, false).unwrap());
1576+
insta::assert_snapshot!(generate(
1577+
contents,
1578+
ParserOpts {
1579+
mode: ParserMode::Standalone,
1580+
}
1581+
)
1582+
.unwrap());
15431583
});
15441584
}
15451585
};
@@ -1550,7 +1590,13 @@ mod test {
15501590
#[test]
15511591
fn $name() {
15521592
let vim_contents = include_str!($path);
1553-
let lua_contents = generate(vim_contents, true).unwrap();
1593+
let lua_contents = generate(
1594+
vim_contents,
1595+
ParserOpts {
1596+
mode: ParserMode::Test,
1597+
},
1598+
)
1599+
.unwrap();
15541600

15551601
let filepath = concat!(
15561602
env!("CARGO_MANIFEST_DIR"),
@@ -1608,7 +1654,13 @@ mod test {
16081654
export var x = MyCoolFunc() + 1
16091655
"#;
16101656

1611-
let generated = generate(contents, false).unwrap();
1657+
let generated = generate(
1658+
contents,
1659+
ParserOpts {
1660+
mode: ParserMode::Standalone,
1661+
},
1662+
)
1663+
.unwrap();
16121664
let eval = exec_lua(&generated).unwrap();
16131665
assert_eq!(eval["x"], 6.into());
16141666
}
@@ -1621,7 +1673,13 @@ mod test {
16211673
export var x = len("hello")
16221674
"#;
16231675

1624-
let generated = generate(contents, false).unwrap();
1676+
let generated = generate(
1677+
contents,
1678+
ParserOpts {
1679+
mode: ParserMode::Standalone,
1680+
},
1681+
)
1682+
.unwrap();
16251683
let eval = exec_lua(&generated).unwrap();
16261684
assert_eq!(eval["x"], 5.into());
16271685
}
@@ -1643,7 +1701,13 @@ mod test {
16431701
export var x = len(nvim_get_autocmds({group: "matchparen"}))
16441702
"#;
16451703

1646-
let generated = generate(contents, false).unwrap();
1704+
let generated = generate(
1705+
contents,
1706+
ParserOpts {
1707+
mode: ParserMode::Standalone,
1708+
},
1709+
)
1710+
.unwrap();
16471711
let eval = exec_lua(&generated).unwrap();
16481712
assert_eq!(eval["x"], 4.into());
16491713
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ describe("filename", function()
2727

2828
-- Actual test
2929
local x = true
30-
if NVIM9.bool(NVIM9.ops["Or"](NVIM9.prefix["Bang"](NVIM9.fn["has"]("vim9script")), vim.v["version"] < 900)) then
30+
if NVIM9.bool(NVIM9.ops["Or"](NVIM9.prefix["Bang"](NVIM9.fn["has"]("vim9script")), 900 < 900)) then
3131
x = false
3232
end
3333

lua/vim9script/convert.lua

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)