Skip to content

Commit

Permalink
fix: add error for non-default args following default args
Browse files Browse the repository at this point in the history
  • Loading branch information
vberlier committed Sep 12, 2022
1 parent cec87b2 commit 2af9854
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 66 deletions.
7 changes: 7 additions & 0 deletions bolt/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1039,6 +1039,7 @@ def parse_function_signature(stream: TokenStream) -> AstFunctionSignature:
new_locals: Set[str] = set()

encountered_positional = False
encountered_default = False
encountered_variadic = False
encountered_variadic_keyword = False
expect_named_argument = False
Expand Down Expand Up @@ -1077,10 +1078,16 @@ def parse_function_signature(stream: TokenStream) -> AstFunctionSignature:

default = None
if stream.get("equal"):
encountered_default = True
with stream.provide(
identifiers=scoped_identifiers | new_locals
):
default = delegate("bolt:expression", stream)
elif encountered_default:
exc = InvalidSyntax(
"Argument without default can not appear after arguments with default values."
)
raise set_location(exc, token)

argument = AstFunctionSignatureArgument(
name=name.value,
Expand Down
2 changes: 1 addition & 1 deletion examples/bolt_function_signature/beet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ require:
- bolt
data_pack:
load:
data/demo/functions/foo: "foo.mcfunction"
data/demo/functions/foo.mcfunction: "foo.mcfunction"
pipeline:
- mecha
4 changes: 2 additions & 2 deletions examples/bolt_function_signature/foo.mcfunction
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def f(a=1,):
def f(a=1, /):
pass

def f(a=1, /, b):
def f(a, /, b):
pass

def f(a=1, /, b=2):
Expand All @@ -22,7 +22,7 @@ def f(a=1, /, b=2):
def f(a=1, /, b=2, *args):
pass

def f(a=1, /, b=2, *, c):
def f(a, /, b, *, c):
pass

def f(a=1, /, b=2, *, c=3):
Expand Down
7 changes: 5 additions & 2 deletions tests/resources/bolt_examples.mcfunction
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ def f(a=1,):
def f(a=1, /):
pass
###
def f(a=1, /, b):
def f(a, /, b):
pass
###
def f(a=1, /, b=2):
Expand All @@ -1065,7 +1065,7 @@ def f(a=1, /, b=2):
def f(a=1, /, b=2, *args):
pass
###
def f(a=1, /, b=2, *, c):
def f(a, /, b, *, c):
pass
###
def f(a=1, /, b=2, *, c=3):
Expand Down Expand Up @@ -1103,3 +1103,6 @@ def g(foo, /, bar, /):
###
def g(foo, *args, bar, *args):
pass
###
def g(a=1, b):
pass
32 changes: 14 additions & 18 deletions tests/snapshots/bolt__parse_288__0.txt
Original file line number Diff line number Diff line change
@@ -1,46 +1,42 @@
def f(a=1, /, b):
def f(a, /, b):
pass
---
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=26, lineno=2, colno=9)
end_location: SourceLocation(pos=24, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=26, lineno=2, colno=9)
end_location: SourceLocation(pos=24, lineno=2, colno=9)
identifier: 'def:function:body'
arguments:
<class 'bolt.ast.AstFunctionSignature'>
location: SourceLocation(pos=4, lineno=1, colno=5)
end_location: SourceLocation(pos=16, lineno=1, colno=17)
end_location: SourceLocation(pos=14, lineno=1, colno=15)
decorators:
<empty>
name: 'f'
arguments:
<class 'bolt.ast.AstFunctionSignatureArgument'>
location: SourceLocation(pos=6, lineno=1, colno=7)
end_location: SourceLocation(pos=9, lineno=1, colno=10)
end_location: SourceLocation(pos=7, lineno=1, colno=8)
name: 'a'
default:
<class 'bolt.ast.AstValue'>
location: SourceLocation(pos=8, lineno=1, colno=9)
end_location: SourceLocation(pos=9, lineno=1, colno=10)
value: 1
default: None
<class 'bolt.ast.AstFunctionSignaturePositionalMarker'>
location: SourceLocation(pos=11, lineno=1, colno=12)
end_location: SourceLocation(pos=12, lineno=1, colno=13)
location: SourceLocation(pos=9, lineno=1, colno=10)
end_location: SourceLocation(pos=10, lineno=1, colno=11)
<class 'bolt.ast.AstFunctionSignatureArgument'>
location: SourceLocation(pos=14, lineno=1, colno=15)
end_location: SourceLocation(pos=15, lineno=1, colno=16)
location: SourceLocation(pos=12, lineno=1, colno=13)
end_location: SourceLocation(pos=13, lineno=1, colno=14)
name: 'b'
default: None
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=22, lineno=2, colno=5)
end_location: SourceLocation(pos=26, lineno=2, colno=9)
location: SourceLocation(pos=20, lineno=2, colno=5)
end_location: SourceLocation(pos=24, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
location: SourceLocation(pos=22, lineno=2, colno=5)
end_location: SourceLocation(pos=26, lineno=2, colno=9)
location: SourceLocation(pos=20, lineno=2, colno=5)
end_location: SourceLocation(pos=24, lineno=2, colno=9)
identifier: 'pass'
arguments:
<empty>
8 changes: 2 additions & 6 deletions tests/snapshots/bolt__parse_288__1.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
_bolt_lineno = [1], [1]
_bolt_helper_missing = _bolt_runtime.helpers['missing']
_bolt_helper_children = _bolt_runtime.helpers['children']
_bolt_helper_replace = _bolt_runtime.helpers['replace']
with _bolt_runtime.scope() as _bolt_var0:
def f(a=_bolt_helper_missing, /, b):
if a is _bolt_helper_missing:
_bolt_var0 = 1
a = _bolt_var0
def f(a, /, b):
pass
_bolt_var1 = _bolt_helper_replace(_bolt_refs[0], commands=_bolt_helper_children(_bolt_var0))
---
Expand All @@ -15,6 +11,6 @@ output = _bolt_var1
_bolt_refs[0]
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=26, lineno=2, colno=9)
end_location: SourceLocation(pos=24, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
46 changes: 19 additions & 27 deletions tests/snapshots/bolt__parse_291__0.txt
Original file line number Diff line number Diff line change
@@ -1,58 +1,50 @@
def f(a=1, /, b=2, *, c):
def f(a, /, b, *, c):
pass
---
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=34, lineno=2, colno=9)
end_location: SourceLocation(pos=30, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=34, lineno=2, colno=9)
end_location: SourceLocation(pos=30, lineno=2, colno=9)
identifier: 'def:function:body'
arguments:
<class 'bolt.ast.AstFunctionSignature'>
location: SourceLocation(pos=4, lineno=1, colno=5)
end_location: SourceLocation(pos=24, lineno=1, colno=25)
end_location: SourceLocation(pos=20, lineno=1, colno=21)
decorators:
<empty>
name: 'f'
arguments:
<class 'bolt.ast.AstFunctionSignatureArgument'>
location: SourceLocation(pos=6, lineno=1, colno=7)
end_location: SourceLocation(pos=9, lineno=1, colno=10)
end_location: SourceLocation(pos=7, lineno=1, colno=8)
name: 'a'
default:
<class 'bolt.ast.AstValue'>
location: SourceLocation(pos=8, lineno=1, colno=9)
end_location: SourceLocation(pos=9, lineno=1, colno=10)
value: 1
default: None
<class 'bolt.ast.AstFunctionSignaturePositionalMarker'>
location: SourceLocation(pos=11, lineno=1, colno=12)
end_location: SourceLocation(pos=12, lineno=1, colno=13)
location: SourceLocation(pos=9, lineno=1, colno=10)
end_location: SourceLocation(pos=10, lineno=1, colno=11)
<class 'bolt.ast.AstFunctionSignatureArgument'>
location: SourceLocation(pos=14, lineno=1, colno=15)
end_location: SourceLocation(pos=17, lineno=1, colno=18)
location: SourceLocation(pos=12, lineno=1, colno=13)
end_location: SourceLocation(pos=13, lineno=1, colno=14)
name: 'b'
default:
<class 'bolt.ast.AstValue'>
location: SourceLocation(pos=16, lineno=1, colno=17)
end_location: SourceLocation(pos=17, lineno=1, colno=18)
value: 2
default: None
<class 'bolt.ast.AstFunctionSignatureVariadicMarker'>
location: SourceLocation(pos=19, lineno=1, colno=20)
end_location: SourceLocation(pos=20, lineno=1, colno=21)
location: SourceLocation(pos=15, lineno=1, colno=16)
end_location: SourceLocation(pos=16, lineno=1, colno=17)
<class 'bolt.ast.AstFunctionSignatureArgument'>
location: SourceLocation(pos=22, lineno=1, colno=23)
end_location: SourceLocation(pos=23, lineno=1, colno=24)
location: SourceLocation(pos=18, lineno=1, colno=19)
end_location: SourceLocation(pos=19, lineno=1, colno=20)
name: 'c'
default: None
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=30, lineno=2, colno=5)
end_location: SourceLocation(pos=34, lineno=2, colno=9)
location: SourceLocation(pos=26, lineno=2, colno=5)
end_location: SourceLocation(pos=30, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
location: SourceLocation(pos=30, lineno=2, colno=5)
end_location: SourceLocation(pos=34, lineno=2, colno=9)
location: SourceLocation(pos=26, lineno=2, colno=5)
end_location: SourceLocation(pos=30, lineno=2, colno=9)
identifier: 'pass'
arguments:
<empty>
11 changes: 2 additions & 9 deletions tests/snapshots/bolt__parse_291__1.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
_bolt_lineno = [1], [1]
_bolt_helper_missing = _bolt_runtime.helpers['missing']
_bolt_helper_children = _bolt_runtime.helpers['children']
_bolt_helper_replace = _bolt_runtime.helpers['replace']
with _bolt_runtime.scope() as _bolt_var0:
def f(a=_bolt_helper_missing, /, b=_bolt_helper_missing, *, c):
if a is _bolt_helper_missing:
_bolt_var0 = 1
a = _bolt_var0
if b is _bolt_helper_missing:
_bolt_var1 = 2
b = _bolt_var1
def f(a, /, b, *, c):
pass
_bolt_var1 = _bolt_helper_replace(_bolt_refs[0], commands=_bolt_helper_children(_bolt_var0))
---
Expand All @@ -18,6 +11,6 @@ output = _bolt_var1
_bolt_refs[0]
<class 'mecha.ast.AstRoot'>
location: SourceLocation(pos=0, lineno=1, colno=1)
end_location: SourceLocation(pos=34, lineno=2, colno=9)
end_location: SourceLocation(pos=30, lineno=2, colno=9)
commands:
<class 'mecha.ast.AstCommand'>
7 changes: 7 additions & 0 deletions tests/snapshots/bolt__parse_304__0.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#>ERROR Argument without default can not appear after arguments with default values.
# line 1, column 12
# 1 | def g(a=1, b):
# : ^
# 2 | pass
def g(a=1, b):
pass
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
# Lectern snapshot

The data pack and resource pack are empty.
## Data pack

`@data_pack pack.mcmeta`

```json
{
"pack": {
"pack_format": 10,
"description": ""
}
}
```

### demo

`@function(strip_final_newline) demo:foo`

```mcfunction
```

0 comments on commit 2af9854

Please sign in to comment.