Skip to content
This repository has been archived by the owner on Sep 12, 2024. It is now read-only.

trailing comma are supported for dict, list, set, import, can. #579

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions jaclang/compiler/jac.lark
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ from_path: (DOT | ELLIPSIS)* import_path
| (DOT | ELLIPSIS)+

import_path: named_ref (DOT named_ref)* (KW_AS NAME)?
import_items: (import_item COMMA)* import_item
import_items: (import_item COMMA)* import_item COMMA?
import_item: named_ref (KW_AS NAME)?
sub_name: COLON NAME
include_stmt: KW_INCLUDE sub_name? import_path SEMI
Expand Down Expand Up @@ -63,7 +63,7 @@ enum: decorators? enum_decl

enum_decl: KW_ENUM access_tag? STRING? NAME inherited_archs? (enum_block | SEMI)
enum_def: arch_to_enum_chain enum_block
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt)? RBRACE
enum_block: LBRACE ((enum_stmt COMMA)* enum_stmt COMMA?)? RBRACE

enum_stmt: NAME (COLON STRING)? EQ expression
| NAME (COLON STRING)?
Expand All @@ -83,7 +83,7 @@ abstract_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (
genai_ability: KW_OVERRIDE? KW_STATIC? KW_CAN access_tag? STRING? named_ref (func_decl) KW_BY atomic_call SEMI
event_clause: KW_WITH expression? (KW_EXIT | KW_ENTRY) (STRING? RETURN_HINT expression)?
func_decl: (LPAREN func_decl_params? RPAREN)? (RETURN_HINT (STRING COLON)? expression)?
func_decl_params: (param_var COMMA)* param_var
func_decl_params: (param_var COMMA)* param_var COMMA?
param_var: (STAR_POW | STAR_MUL)? NAME (COLON STRING)? type_tag (EQ expression)?

// Global variables
Expand Down Expand Up @@ -412,10 +412,10 @@ set_compr: LBRACE expression inner_compr+ RBRACE
dict_compr: LBRACE kv_pair inner_compr+ RBRACE
inner_compr: KW_ASYNC? KW_FOR atomic_chain KW_IN pipe_call (KW_IF walrus_assign)*

dict_val: LBRACE ((kv_pair COMMA)* kv_pair)? RBRACE
list_val: LSQUARE expr_list? RSQUARE
dict_val: LBRACE ((kv_pair COMMA)* kv_pair COMMA?)? RBRACE
list_val: LSQUARE (expr_list COMMA?)? RSQUARE
tuple_val: LPAREN tuple_list? RPAREN
set_val: LBRACE expr_list RBRACE
set_val: LBRACE expr_list COMMA? RBRACE

kv_pair: expression COLON expression | STAR_POW expression
expr_list: (expr_list COMMA)? expression
Expand Down
64 changes: 64 additions & 0 deletions jaclang/tests/fixtures/trailing_comma.jac
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
"""
This test file is to ensure the valid syntax of jac lang.
Add new jac syntax here to test if it compile without any issue.
"""

# Import statement without trailing comma.
import:py from time {
sleep,
timezone,
tzname
}


# Import statement with trailing comma.
import:py from os {
path,
getenv,
getpid,
}


enum WithoutTrailComma {
FOO = "FOO",
BAR = "BAR"
}


enum WithTrailComma {
FOO = "FOO",
BAR = "BAR",
}


can without_trail_comma(a:int, b:int) {}

can with_trail_comma(
a:int,
b:int,
c:int,
) {}


with entry {

dict_without_trail_comma = { "key" : "value" };
dict_with_trail_comma = {
"key" : "val",
};

list_without_trail_comma = [ "foo", "bar" ];
list_with_trail_comma = [
"foo",
"bar",
];

set_without_trail_comma = { "foo", "bar" };
set_with_trail_comma = {
"foo",
"bar",
};

print("Code compiled and ran successfully!");
}

9 changes: 9 additions & 0 deletions jaclang/tests/test_language.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,15 @@ def test_tuple_unpack(self) -> None:
self.assertIn("1", stdout_value[0])
self.assertIn("[2, 3, 4]", stdout_value[1])

def test_trailing_comma(self) -> None:
"""Test trailing comma."""
captured_output = io.StringIO()
sys.stdout = captured_output
jac_import("trailing_comma", base_path=self.fixture_abs_path("./"))
sys.stdout = sys.__stdout__
stdout_value = captured_output.getvalue()
self.assertIn("Code compiled and ran successfully!", stdout_value)

def test_try_finally(self) -> None:
"""Test try finally."""
captured_output = io.StringIO()
Expand Down
Loading