diff --git a/coconut/compiler/compiler.py b/coconut/compiler/compiler.py index 036aefc25..21be94792 100644 --- a/coconut/compiler/compiler.py +++ b/coconut/compiler/compiler.py @@ -1630,16 +1630,8 @@ def str_proc(self, inputstring, **kwargs): # start the string hold if we're at the start of a string if hold is not None: - is_f = False - j = i - len(hold["start"]) - while j >= 0: - prev_c = inputstring[j] - if prev_c == "f": - is_f = True - break - elif prev_c != "r": - break - j -= 1 + is_f_check_str = inputstring[clip(i - len(hold["start"]) + 1 - self.start_f_str_regex_len, min=0): i - len(hold["start"]) + 1] + is_f = self.start_f_str_regex.search(is_f_check_str) if is_f: hold.update({ "type": "f string", diff --git a/coconut/compiler/grammar.py b/coconut/compiler/grammar.py index 0a30dd146..3cf73fb22 100644 --- a/coconut/compiler/grammar.py +++ b/coconut/compiler/grammar.py @@ -817,7 +817,7 @@ class Grammar(object): octint = combine(Word("01234567") + ZeroOrMore(underscore.suppress() + Word("01234567"))) hexint = combine(Word(hexnums) + ZeroOrMore(underscore.suppress() + Word(hexnums))) - imag_j = caseless_literal("j") | fixto(caseless_literal("i", suppress=True), "j") + imag_j = caseless_literal("j") | fixto(caseless_literal("i", suppress=True, disambiguate=True), "j") basenum = combine( Optional(integer) + dot + integer | integer + Optional(dot + Optional(integer)) @@ -2660,6 +2660,9 @@ class Grammar(object): | fixto(end_of_line, "misplaced newline (maybe missing ':')") ) + start_f_str_regex = compile_regex(r"\br?fr?$") + start_f_str_regex_len = 4 + end_f_str_expr = combine(start_marker + (rbrace | colon | bang)) string_start = start_marker + python_quoted_string diff --git a/coconut/compiler/util.py b/coconut/compiler/util.py index 4d7074ca6..5e2cd75ac 100644 --- a/coconut/compiler/util.py +++ b/coconut/compiler/util.py @@ -131,6 +131,7 @@ cache_validation_info, require_cache_clear_frac, reverse_any_of, + all_keywords, ) from coconut.exceptions import ( CoconutException, @@ -1537,12 +1538,16 @@ def any_len_perm_at_least_one(*elems, **kwargs): return any_len_perm_with_one_of_each_group(*groups_and_elems) -def caseless_literal(literalstr, suppress=False): +def caseless_literal(literalstr, suppress=False, disambiguate=False): """Version of CaselessLiteral that always parses to the given literalstr.""" + out = CaselessLiteral(literalstr) if suppress: - return CaselessLiteral(literalstr).suppress() + out = out.suppress() else: - return fixto(CaselessLiteral(literalstr), literalstr) + out = fixto(out, literalstr) + if disambiguate: + out = disallow_keywords(k for k in all_keywords if k.startswith((literalstr[0].lower(), literalstr[0].upper()))) + out + return out # ----------------------------------------------------------------------------------------------------------------------- diff --git a/coconut/constants.py b/coconut/constants.py index 86f1592bc..146c9210e 100644 --- a/coconut/constants.py +++ b/coconut/constants.py @@ -37,7 +37,7 @@ def fixpath(path): return os.path.normpath(os.path.realpath(os.path.expanduser(path))) -def get_bool_env_var(env_var, default=False): +def get_bool_env_var(env_var, default=None): """Get a boolean from an environment variable.""" boolstr = os.getenv(env_var, "").lower() if boolstr in ("true", "yes", "on", "1", "t"): diff --git a/coconut/root.py b/coconut/root.py index ffe859e89..22fca3377 100644 --- a/coconut/root.py +++ b/coconut/root.py @@ -26,7 +26,7 @@ VERSION = "3.0.4" VERSION_NAME = None # False for release, int >= 1 for develop -DEVELOP = 12 +DEVELOP = 13 ALPHA = False # for pre releases rather than post releases assert DEVELOP is False or DEVELOP >= 1, "DEVELOP must be False or an int >= 1" diff --git a/coconut/terminal.py b/coconut/terminal.py index 7247c7641..ee1a9335c 100644 --- a/coconut/terminal.py +++ b/coconut/terminal.py @@ -210,7 +210,7 @@ def __init__(self, other=None): @classmethod def enable_colors(cls, file=None): """Attempt to enable CLI colors.""" - use_color = get_bool_env_var(use_color_env_var) + use_color = get_bool_env_var(use_color_env_var, default=None) if ( use_color is False or use_color is None and file is not None and not isatty(file) diff --git a/coconut/tests/src/cocotest/agnostic/primary_2.coco b/coconut/tests/src/cocotest/agnostic/primary_2.coco index ccee37e55..3d7acdbd8 100644 --- a/coconut/tests/src/cocotest/agnostic/primary_2.coco +++ b/coconut/tests/src/cocotest/agnostic/primary_2.coco @@ -424,6 +424,10 @@ def primary_test_2() -> bool: assert all_equal([], to=10) assert all_equal([10; 10; 10; 10], to=10) assert not all_equal([1, 1], to=10) + assert not 0in[1,2,3] + if"0":assert True + if"0": + assert True with process_map.multiple_sequential_calls(): # type: ignore assert map((+), range(3), range(4)$[:-1], strict=True) |> list == [0, 2, 4] == process_map((+), range(3), range(4)$[:-1], strict=True) |> list # type: ignore