Skip to content

Commit

Permalink
Support Luau floor division (//) (#291)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnnyMorganz authored Nov 4, 2023
1 parent a07d208 commit a359e3a
Show file tree
Hide file tree
Showing 8 changed files with 339 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased
### Added
- Added support for parsing Luau's floor division `//`

### Changed
- Flattened `Expression::Value` to all be variants of `Expression` directly, as this was not used anywhere else. The extra `type_assertion` field has been moved into a new variant `Expression::TypeAssertion`. None of these variants are boxed.
- The following fields/variants have been changed from `Expression` to `Box<Expression>`: `Prefix::Expression`, `Var::Expression`, `IfExpression::condition`, `IfExpression::if_expression`, `IfExpression::else_expression`.
Expand Down
7 changes: 5 additions & 2 deletions full-moon/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,7 @@ make_op!(BinOp,
TwoEqual,
#[cfg(feature = "lua53")]
Ampersand,
#[cfg(feature = "lua53")]
#[cfg(any(feature = "roblox", feature = "lua53"))]
DoubleSlash,
#[cfg(feature = "lua53")]
DoubleLessThan,
Expand All @@ -2049,6 +2049,8 @@ impl BinOp {
match *self {
BinOp::Caret(_) => 8,
BinOp::Star(_) | BinOp::Slash(_) | BinOp::Percent(_) => 6,
#[cfg(feature = "roblox")]
BinOp::DoubleSlash(_) => 6,
BinOp::Plus(_) | BinOp::Minus(_) => 5,
BinOp::TwoDots(_) => 4,
BinOp::GreaterThan(_)
Expand Down Expand Up @@ -2110,9 +2112,10 @@ impl BinOp {
| BinOp::TildeEqual(token)
| BinOp::TwoDots(token)
| BinOp::TwoEqual(token) => token,
#[cfg(any(feature = "roblox", feature = "lua53"))]
BinOp::DoubleSlash(token) => token,
#[cfg(feature = "lua53")]
BinOp::Ampersand(token)
| BinOp::DoubleSlash(token)
| BinOp::DoubleLessThan(token)
| BinOp::Pipe(token)
| BinOp::DoubleGreaterThan(token)
Expand Down
8 changes: 6 additions & 2 deletions full-moon/src/ast/parsers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2221,12 +2221,16 @@ define_parser!(ParseBinOp, BinOp, |_, state| {
} else if let Ok((state, operator)) = ParseSymbol(Symbol::TwoEqual).parse(state) {
Ok((state, BinOp::TwoEqual(operator)))
} else {
// Luau & Lua 5.3
#[cfg(any(feature = "roblox", feature = "lua53"))]
if let Ok((state, operator)) = ParseSymbol(Symbol::DoubleSlash).parse(state) {
return Ok((state, BinOp::DoubleSlash(operator)));
}

// Lua 5.3
#[cfg(feature = "lua53")]
if let Ok((state, operator)) = ParseSymbol(Symbol::Ampersand).parse(state) {
return Ok((state, BinOp::Ampersand(operator)));
} else if let Ok((state, operator)) = ParseSymbol(Symbol::DoubleSlash).parse(state) {
return Ok((state, BinOp::DoubleSlash(operator)));
} else if let Ok((state, operator)) = ParseSymbol(Symbol::DoubleLessThan).parse(state) {
return Ok((state, BinOp::DoubleLessThan(operator)));
} else if let Ok((state, operator)) = ParseSymbol(Symbol::Pipe).parse(state) {
Expand Down
2 changes: 1 addition & 1 deletion full-moon/src/atom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ pub(crate) enum Atom {
#[token("/")]
Slash,

#[cfg(feature = "lua53")]
#[cfg(any(feature = "roblox", feature = "lua53"))]
#[token("//")]
DoubleSlash,

Expand Down
6 changes: 3 additions & 3 deletions full-moon/src/tokenizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ pub enum Symbol {
#[cfg_attr(feature = "serde", serde(rename = "/"))]
Slash,

#[cfg(feature = "lua53")]
#[cfg(any(feature = "roblox", feature = "lua53"))]
#[cfg_attr(feature = "serde", serde(rename = "//"))]
DoubleSlash,

Expand Down Expand Up @@ -265,7 +265,7 @@ impl TryFrom<Atom> for Symbol {
Atom::RightParen => Symbol::RightParen,
Atom::Semicolon => Symbol::Semicolon,
Atom::Slash => Symbol::Slash,
#[cfg(feature = "lua53")]
#[cfg(any(feature = "roblox", feature = "lua53"))]
Atom::DoubleSlash => Symbol::DoubleSlash,
Atom::Star => Symbol::Star,
#[cfg(feature = "lua53")]
Expand Down Expand Up @@ -349,7 +349,7 @@ impl Display for Symbol {
Symbol::RightParen => ")",
Symbol::Semicolon => ";",
Symbol::Slash => "/",
#[cfg(feature = "lua53")]
#[cfg(any(feature = "roblox", feature = "lua53"))]
Symbol::DoubleSlash => "//",
Symbol::Star => "*",
#[cfg(feature = "lua53")]
Expand Down
173 changes: 173 additions & 0 deletions full-moon/tests/roblox_cases/pass/floor_division/ast.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
---
source: full-moon/tests/pass_cases.rs
expression: ast.nodes()
---
stmts:
- - LocalAssignment:
local_token:
leading_trivia: []
token:
start_position:
bytes: 0
line: 1
character: 1
end_position:
bytes: 5
line: 1
character: 6
token_type:
type: Symbol
symbol: local
trailing_trivia:
- start_position:
bytes: 5
line: 1
character: 6
end_position:
bytes: 6
line: 1
character: 7
token_type:
type: Whitespace
characters: " "
name_list:
pairs:
- End:
leading_trivia: []
token:
start_position:
bytes: 6
line: 1
character: 7
end_position:
bytes: 7
line: 1
character: 8
token_type:
type: Identifier
identifier: x
trailing_trivia:
- start_position:
bytes: 7
line: 1
character: 8
end_position:
bytes: 8
line: 1
character: 9
token_type:
type: Whitespace
characters: " "
equal_token:
leading_trivia: []
token:
start_position:
bytes: 8
line: 1
character: 9
end_position:
bytes: 9
line: 1
character: 10
token_type:
type: Symbol
symbol: "="
trailing_trivia:
- start_position:
bytes: 9
line: 1
character: 10
end_position:
bytes: 10
line: 1
character: 11
token_type:
type: Whitespace
characters: " "
expr_list:
pairs:
- End:
BinaryOperator:
lhs:
Number:
leading_trivia: []
token:
start_position:
bytes: 10
line: 1
character: 11
end_position:
bytes: 11
line: 1
character: 12
token_type:
type: Number
text: "1"
trailing_trivia:
- start_position:
bytes: 11
line: 1
character: 12
end_position:
bytes: 12
line: 1
character: 13
token_type:
type: Whitespace
characters: " "
binop:
DoubleSlash:
leading_trivia: []
token:
start_position:
bytes: 12
line: 1
character: 13
end_position:
bytes: 14
line: 1
character: 15
token_type:
type: Symbol
symbol: //
trailing_trivia:
- start_position:
bytes: 14
line: 1
character: 15
end_position:
bytes: 15
line: 1
character: 16
token_type:
type: Whitespace
characters: " "
rhs:
Number:
leading_trivia: []
token:
start_position:
bytes: 15
line: 1
character: 16
end_position:
bytes: 16
line: 1
character: 17
token_type:
type: Number
text: "2"
trailing_trivia:
- start_position:
bytes: 16
line: 1
character: 17
end_position:
bytes: 17
line: 1
character: 17
token_type:
type: Whitespace
characters: "\n"
- ~

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
local x = 1 // 2
Loading

0 comments on commit a359e3a

Please sign in to comment.