diff --git a/jac/examples/manual_code/circle.jac b/jac/examples/manual_code/circle.jac index 755fab2bf8..276dbd869d 100644 --- a/jac/examples/manual_code/circle.jac +++ b/jac/examples/manual_code/circle.jac @@ -1,77 +1,110 @@ -""" -This module demonstrates a simple circle class and a function to calculate -the area of a circle in all of Jac's glory. -""" +with entry{ + aaaaaaaaaaa = 1; #1 0-4 + jkjkj=898; ioio=89; # 2 3 5-9 10-14 + oioi=8; uiui=90; # 4 5 15-19 20-24 + oioi=8; uiuiwewweweweweweew=90; # 6 7 25-29 30-34 + bbb = 1; iiii = 1; opopo=9; # 8 9 10 35-39 40-44 45-49 + oioi=8; uiui=90; # 11 12 50-54 55-59 -import:py math; -# Module-level global var -glob RAD = 5; + # ljklllk + # /lklklklklk +# klklklkl +# klklklkl -"""Function to calculate the area of a circle.""" -can calculate_area(radius: float) -> float { - return math.pi * radius * radius; -} -#* (This is multiline comments in Jac) -Above we have the demonstration of a function to calculate the area of a circle. -Below we have the demonstration of a class to calculate the area of a circle. -*# - -"""Enum for shape types""" -enum ShapeType { - CIRCLE = "Circle", - UNKNOWN = "Unknown" -} + # ljklllk + # ljklllk -"""Base class for a shape.""" -obj Shape { - has shape_type: ShapeType; +# jjkjkjkjk # - """Abstract method to calculate the area of a shape.""" - can area -> float abs; + # ljklllk + # ljjlkjkjkjkj + ccccccaaaaa = 3; opop=8; uuuuuuuuuuuuuuuu= 1; # 13 14 15 60-64 65-69 70-74 + fffoooooooooooo = 1; kkkkkk=8; oo=9; ppppppppppppppppp= 1; # 16 17 18 19 75-79 80-84 85-89 90-94 + # ljklllk +# w + d = 2; oopopo=9; oooooooooooooooooooooooooooooooooooooooo= 1; # 20 21 22 95-99 100-104 105-109 + # kl + # jjlljljll + ee = 4; # 23 24 110-114 + hj = 1; # 25 26 115-119 } -"""Circle class inherits from Shape.""" -obj Circle :Shape: { - can init(radius: float) { - super.init(ShapeType.CIRCLE); - self.radius = radius; - } - - """Overridden method to calculate the area of the circle.""" - override can area -> float { - return math.pi * self.radius * self.radius; - } -} +# """ +# This module demonstrates a simple circle class and a function to calculate +# the area of a circle in all of Jac's glory. +# """ -with entry { - c = Circle(RAD); -} -# Global also works here - -with entry:__main__ { - # To run the program functionality - print( - f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}" - ); - print( - f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}" - ); -} -# Unit Tests! +# import:py math; +# # Module-level global var -glob expected_area = 78.53981633974483; +# glob RAD = 5; -test calc_area { - check almostEqual(calculate_area(RAD), expected_area); -} +# """Function to calculate the area of a circle.""" +# can calculate_area(radius: float) -> float { +# return math.pi * radius * radius; +# } +# #* (This is multiline comments in Jac) +# Above we have the demonstration of a function to calculate the area of a circle. +# Below we have the demonstration of a class to calculate the area of a circle. +# *# -test circle_area { - c = Circle(RAD); - check almostEqual(c.area(), expected_area); -} +# """Enum for shape types""" +# enum ShapeType { +# CIRCLE = "Circle", +# UNKNOWN = "Unknown" +# } -test circle_type { - c = Circle(RAD); - check c.shape_type == ShapeType.CIRCLE; -} +# """Base class for a shape.""" +# obj Shape { +# has shape_type: ShapeType; + +# """Abstract method to calculate the area of a shape.""" +# can area -> float abs; +# } + +# """Circle class inherits from Shape.""" +# obj Circle :Shape: { +# can init(radius: float) { +# super.init(ShapeType.CIRCLE); +# self.radius = radius; +# self.radius = radius; +# } + +# """Overridden method to calculate the area of the circle.""" +# override can area -> float { +# return math.pi * self.radius * self.radius; +# } +# } + +# with entry { +# c = Circle(RAD); +# } +# # Global also works here + +# with entry:__main__ { +# # To run the program functionality +# print( +# f"Area of a circle with radius {RAD} using function: {calculate_area(RAD)}" +# ); +# print( +# f"Area of a {c.shape_type.value} with radius {RAD} using class: {c.area()}" +# ); +# } +# # Unit Tests! + +# glob expected_area = 78.53981633974483; + +# test calc_area { +# check almostEqual(calculate_area(RAD), expected_area); +# } + +# test circle_area { +# c = Circle(RAD); +# check almostEqual(c.area(), expected_area); +# } + +# test circle_type { +# c = Circle(RAD); +# check c.shape_type == ShapeType.CIRCLE; +# } diff --git a/jac/jaclang/langserve/sem_manager.py b/jac/jaclang/langserve/sem_manager.py index 665f6fe334..107a445841 100644 --- a/jac/jaclang/langserve/sem_manager.py +++ b/jac/jaclang/langserve/sem_manager.py @@ -62,6 +62,23 @@ def gen_sem_tok_node( tokens += [(pos, col_end, length, node)] return tokens + def get_sem_tokens_in_line(self,line: int) -> list[int]: + """Return a list of semantic tokens in line and index as tuple.""" + return [ + (i, get_token_start(i, self.sem_tokens)) + for i in range(0, len(self.sem_tokens), 5) + if get_token_start(i, self.sem_tokens)[0] == line + ] + + def last_up_token(self, line: int) -> list[int]: + """Return the last token before that line and line and index as tuple.""" + tok = None + for i in range(0, len(self.sem_tokens), 5): + if get_token_start(i, self.sem_tokens)[0] >= line: + break + tok = i + return tok, get_token_start(tok, self.sem_tokens) + def update_sem_tokens( self, content_changes: lspt.DidChangeTextDocumentParams, @@ -69,6 +86,156 @@ def update_sem_tokens( document_lines: List[str], ) -> list[int]: """Update semantic tokens on change.""" + import logging + + def find_token_based_on_line(line: int, sem_tokens: list[int]) -> int|int: + for i, j in enumerate( + [get_token_start(i, sem_tokens) for i in range(0, len(sem_tokens), 5)] + ): + if j[0] == line: + return i + 1,1 + if j[0] > line: + return i, 0 + + if len(content_changes.content_changes) == 2: + x1 = content_changes.content_changes[0] + x2 = content_changes.content_changes[1] + change1_start_line = x2.range.start.line + change2_start_line = x2.range.end.line + if change2_start_line > change1_start_line: + x0 = content_changes.content_changes[1] + x1 = content_changes.content_changes[0] + logging.info(f"one \n{x0} two \n{x1}") + logging.info(f'\n\t x1 list \n\t{self.get_sem_tokens_in_line(x1.range.start.line)}') + logging.info(f'\n\t x2 list \n\t{self.get_sem_tokens_in_line(x1.range.end.line)}') + one = x0.range.start.line + two = x0.range.end.line + three = x1.range.start.line + logging.info(f"one {one} two {two} three {three} ") + tok_index_of_ff,p = find_token_based_on_line(one, sem_tokens) + logging.info(f"ff {tok_index_of_ff}") + tok_index_of_pp,p = find_token_based_on_line(two, sem_tokens) + tok_index_of_pp -= 1 + logging.info(f"pp {tok_index_of_pp}") + tok_index_of_oo,p = find_token_based_on_line(three+1, sem_tokens) + tok_index_of_oo -= 1 + logging.info(f"oo {tok_index_of_oo}") + + # add in order after move down + first_1 = sem_tokens[:(tok_index_of_ff-1)*5] + second_2 = sem_tokens[(tok_index_of_ff-1)*5:tok_index_of_pp*5] + third_3 = sem_tokens[tok_index_of_pp*5:tok_index_of_oo*5] + remaining = sem_tokens[tok_index_of_oo*5:] + sem_tokens = first_1 + third_3 + second_2 + remaining + logging.info("Moving down") + self.sem_tokens = sem_tokens + else: + x0 = content_changes.content_changes[0] + x1 = content_changes.content_changes[1] + logging.info(f"one \n{x0} two \n{x1}") + logging.info(f'\n\t one list \n\t{self.get_sem_tokens_in_line(x1.range.start.line)}') + logging.info(f'\n\t dummy list \n\t{self.get_sem_tokens_in_line(x1.range.end.line)}') + logging.info(f'\n\t two list \n\t{self.get_sem_tokens_in_line(x0.range.start.line)}') + logging.info(f'\n\t three list \n\t{self.get_sem_tokens_in_line(x0.range.end.line)}') + two = x0.range.start.line + three = x0.range.end.line + one = x1.range.start.line + on1 = self.get_sem_tokens_in_line(one) + tw2 = self.get_sem_tokens_in_line(two) + th3 = self.get_sem_tokens_in_line(three) + logging.info(f"one {one} two {two} three {three} ") + on_b = self.last_up_token(one) + tw_b = self.last_up_token(two) + th_b = self.last_up_token(three) + logging.info(f"on_b {on_b} tw_b {tw_b} th_b {th_b} ") + + if on1 and tw2 and th3: # DONE + first = sem_tokens[:on1[0][0]] + second = sem_tokens[on1[0][0]:th3[0][0]] + third_3 = sem_tokens[th3[0][0]:th3[-1][0]+5] + bottom = sem_tokens[th3[-1][0]+5:] + + second[0],third_3[0] = third_3[0] ,second[0] + + logging.info(f"first \n{first} \nsecond \n{second} \nthird \n{third_3} \nbottom \n{bottom}") + self.sem_tokens = first + third_3 + second + bottom + return sem_tokens + elif on1 and tw2: # DONE + + sem_tokens[on1[0][0]] += 1 + sem_tokens[tw2[-1][0]+5] -= 1 + + logging.info(f'second ') + return sem_tokens + elif on1 and th3: # swapping + logging.info(f'fourth ') + first = sem_tokens[:on_b[0]+5] + logging.info(f'first {first}') + second = sem_tokens[on_b[0]+5:th3[0][0]] + third_3 = sem_tokens[th3[0][0]:th3[-1][0]+5] + bottom = sem_tokens[th3[-1][0]+5:] + third_3[0],second[0] = second[0],third_3[0] + second[0]= 1 + bottom[0] += three- tw_b[1][0]- 1 + logging.info(f"first \n{first} \nsecond \n{second} \nthird \n{third_3} \nbottom \n{bottom}") + self.sem_tokens = first + third_3 + second + bottom + logging.info(f"sem tokk {sem_tokens}") + return sem_tokens + elif on1: # DONE + sem_tokens[on1[0][0]] += 1 + sem_tokens[th_b[0]+5] -= 1 + logging.info(f'Third == ') + return sem_tokens + elif tw2 and th3: # swapping + logging.info(f'fifth ') + first = sem_tokens[:on_b[0]+5] + second = sem_tokens[on_b[0]+5:th3[0][0]] + third_3 = sem_tokens[th3[0][0]:th3[-1][0]+5] + bottom = sem_tokens[th3[-1][0]+5:] + logging.info(f"first \n{first} \nsecond \n{second} \nthird \n{third_3} \nbottom \n{bottom}") + third_3[0]= one - on_b[1][0] + second[0] = tw_b[1][0] - one+1 + self.sem_tokens = first + third_3 + second + bottom + return sem_tokens + elif th3: # swapping + logging.info(f'sixth ') + l = [on_b[1][0],tw_b[1][0],th_b[1][0]] + # if any in list l is in between one and two + first = sem_tokens[:on_b[0]+5] + second = sem_tokens[on_b[0]+5:th3[0][0]] + third_3 = sem_tokens[th3[0][0]:th3[-1][0]+5] + bottom = sem_tokens[th3[-1][0]+5:] + # swapping + third_3[0]= one - on_b[1][0] + if one < l[0] < two or one < l[1] < two or one < l[2] < two: + logging.info(f'sixth ::--- Exception ') + bottom[0] += three - th_b[1][0] - 1 + # add one to iinside token + second[0] -= third_3[0] -1 + else: + logging.info(f'first \n{first} \nsecond \n{second} \nthird \n{third_3} \nbottom \n{bottom}') + bottom[0] += three - one + # merging + self.sem_tokens = first + third_3 + second + bottom + return sem_tokens + elif tw2: + logging.info(f'seventh ') + sem_tokens[on_b[0]+5] += 1 + sem_tokens[th_b[0]+5] -= 1 + return sem_tokens + else: + l = [on_b[1][0],tw_b[1][0],th_b[1][0]] + # if any in list l is in between one and two + if one < l[0] < two or one < l[1] < two or one < l[2] < two: + logging.info(f'eighth ') + sem_tokens[on_b[0]+5] += 1 + sem_tokens[th_b[0]+5] -= 1 + return sem_tokens + logging.info(f"else //==? ") + + logging.info(f"semmm tok {sem_tokens}") + return sem_tokens + for change in [ x for x in content_changes.content_changes