prthm11 commited on
Commit
c4a2b09
·
verified ·
1 Parent(s): 17e8ef9

Update utils/block_relation_builder.py

Browse files
Files changed (1) hide show
  1. utils/block_relation_builder.py +46 -59
utils/block_relation_builder.py CHANGED
@@ -277,7 +277,7 @@ all_block_definitions = {
277
  "control_stop": {
278
  "block_name": "stop [v]", "block_type": "Control", "block_shape": "Cap Block", "op_code": "control_stop",
279
  "functionality": "Halts all scripts, only the current script, or other scripts within the same sprite. Its shape can dynamically change based on the selected option.",
280
- "inputs": {}, "fields": {"STOP_OPTION": ["all", None]}, "shadow": False, "topLevel": True
281
  },
282
  "control_start_as_clone": {
283
  "block_name": "When I Start as a Clone", "block_type": "Control", "block_shape": "Hat Block", "op_code": "control_start_as_clone",
@@ -1017,7 +1017,6 @@ def parse_reporter_or_value(text, parent_key, pick_key_func, all_generated_block
1017
  # [ORDER NO: ]
1018
  # Variable reporter: [score v] or (score) or just "score"
1019
  m_var = re.fullmatch(r"\[([^\]]+)\s*v\]", text)
1020
-
1021
  if m_var:
1022
  var_name = m_var.group(1).strip()
1023
  print("the reportor block variable: ",var_name)
@@ -1026,18 +1025,18 @@ def parse_reporter_or_value(text, parent_key, pick_key_func, all_generated_block
1026
 
1027
  # [ORDER NO: ]
1028
  m_paren_var = re.fullmatch(r"\(([^)]+)\)", text)
1029
- m_cos = re.fullmatch(r"""\(\s*costume\s+(?:\(\s*(.+?)\s*\)|\[\s*([^\]]+?)\s*v\s*\])\s*\)""",text, re.IGNORECASE | re.VERBOSE)
1030
  if m_paren_var and not m_cos:
1031
- potential_var_name = m_paren_var.group(1).strip()
1032
- print("the potential_var_name variable: ", potential_var_name)
1033
- # *only* treat it as a variable if it contains no arithmetic operators
1034
- if (potential_var_name not in simple_reporters
1035
- and not re.fullmatch(r"-?\d+(\.\d+)?", potential_var_name)
1036
- and not re.search(r"[+\-*/]", potential_var_name)):
1037
- block_id = _register_block("data_variable", parent_key, True, pick_key_func, all_generated_blocks,
1038
- fields={"VARIABLE": [potential_var_name, None]})
1039
  return {"kind": "block", "block": block_id}
1040
-
1041
  # [ORDER NO: ]
1042
  # List reporter: [my list v]
1043
  m_list_reporter = re.fullmatch(r"\[([^\]]+)\s*v\]", text.strip())
@@ -1618,7 +1617,7 @@ def parse_condition(stmt, parent_key, pick_key_func, all_generated_blocks):
1618
  m_not = re.fullmatch(r"\s*(?:<\s*)?not\s+(.+?)(?:\s*>)?\s*", s_lower, re.IGNORECASE)
1619
  if m_not:
1620
  inner = m_not.group(1).strip()
1621
- print("Boolean NOT",m_not)
1622
  inner_obj = parse_condition(inner, parent_key, pick_key_func, all_generated_blocks)
1623
  bid = _register_block("operator_not", parent_key, True, pick_key_func, all_generated_blocks,
1624
  inputs={"OPERAND": inner_obj})
@@ -1714,13 +1713,7 @@ def parse_condition(stmt, parent_key, pick_key_func, all_generated_blocks):
1714
  return {"kind": "block", "block": block_id}
1715
 
1716
  # 5) Touching object: <touching [edge v]?>
1717
- m_touch = re.fullmatch(r"""
1718
- \s*<?\s* # optional leading '<'
1719
- touching\s*\[\s* # 'touching ['
1720
- (?P<sprite>[^\]]+?) # sprite name
1721
- \s*(?:v)?\s*\] # optional 'v' and close ']'
1722
- \s*\?\s*>? # literal '?' and optional '>'
1723
- """, s_lower, re.IGNORECASE | re.VERBOSE)
1724
  if m_touch:
1725
  sprite = m_touch.group('sprite').strip()
1726
  val = {'mouse-pointer':'_mouse_', 'edge':'_edge_'}.get(sprite, sprite)
@@ -1753,11 +1746,20 @@ def parse_condition(stmt, parent_key, pick_key_func, all_generated_blocks):
1753
  return {"kind": "block", "block": block_id}
1754
 
1755
  # 8) Key pressed: <key [key v] pressed?>
1756
- m = re.search(r"key \[([^\]]+)\s*v\] pressed\?", s_lower)
 
 
 
 
 
 
 
 
 
1757
  if m:
1758
  option = m.group(1).strip()
1759
  menu_block_id = _register_block("sensing_keyoptions", parent_key, True, pick_key_func, all_generated_blocks, fields={"KEY_OPTION": [option, None]})
1760
- print("<key [key v] pressed?> : ",option)
1761
  inputs = {"KEY_OPTION": {"kind": "block", "block": menu_block_id}}
1762
  block_id = _register_block("sensing_keypressed", parent_key, True, pick_key_func, all_generated_blocks, inputs=inputs)
1763
  all_generated_blocks[menu_block_id]["parent"] = block_id
@@ -1785,7 +1787,7 @@ def classify(line):
1785
  Order of checks matters: more specific patterns should come before more general ones.
1786
  """
1787
  l = line.lower().strip()
1788
-
1789
  # Ignore comments
1790
  if l.startswith("//"): return None, None
1791
 
@@ -1960,7 +1962,7 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
1960
  while i < len(lines):
1961
  raw_line = lines[i]
1962
  stripped_line = raw_line.strip()
1963
-
1964
  # Skip empty lines and comments
1965
  if not stripped_line or stripped_line.startswith("//"):
1966
  i += 1
@@ -1993,6 +1995,7 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
1993
  # Pop the current substack's scope
1994
  popped_indent, popped_owner_key, popped_last_block_in_chain = stack.pop()
1995
  if popped_last_block_in_chain:
 
1996
  all_generated_blocks[popped_last_block_in_chain]["next"] = None
1997
 
1998
  # If the popped scope had an owner (C-block or procedure definition),
@@ -2036,9 +2039,11 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
2036
  current_scope_indent, current_owner_block_id, last_block_in_current_chain = stack[-1]
2037
 
2038
  # Classify the statement and create the block
2039
- stmt_for_parse = stripped_line.rstrip("then").strip()
 
 
2040
  opcode, ntype = classify(stmt_for_parse)
2041
-
2042
  if opcode is None: # Should not happen if classify is robust
2043
  i += 1
2044
  continue
@@ -2238,7 +2243,9 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
2238
  if m_item: info["inputs"]["ITEM"] = {"kind": "value", "value": m_item.group(1).strip()}
2239
  elif opcode == "event_whengreaterthan":
2240
  #m = re.search(r">\s*\(\s*(-?\d+(\.\d+)?)\s*\)", stmt_for_parse, re.IGNORECASE)
2241
- m = re.search(r""">\s*(?:\(\s*)?(.*?)(?:\s*\))?""", stmt_for_parse, re.IGNORECASE | re.VERBOSE)
 
 
2242
  #if m: info["inputs"]["VALUE"] = {"kind": "value", "value": float(m.group(1)) if '.' in m.group(1) else int(m.group(1))}
2243
  if m: info["inputs"]["VALUE"] = parse_reporter_or_value(m.group(1).strip(), key, pick_key, all_generated_blocks)
2244
 
@@ -2341,6 +2348,7 @@ def generate_plan(generated_input, opcode_keys, pseudo_code):
2341
  m = re.search(r"switch costume to\s*\[([^\]]+)\s*v\]", stmt_for_parse, re.IGNORECASE)
2342
  if m:
2343
  option = m.group(1).strip()
 
2344
  menu_block_id = _register_block("looks_costume", key, True, pick_key, all_generated_blocks, fields={"COSTUME": [option, None]})
2345
  info["inputs"]["COSTUME"] = {"kind": "block", "block": menu_block_id}
2346
  elif opcode in ["looks_switchbackdropto", "looks_switchbackdroptowait"]:
@@ -3058,39 +3066,18 @@ def block_builder(opcode_count,pseudo_code):
3058
  #################################################################################################################################################################
3059
 
3060
  initial_opcode_counts = [
3061
- {"opcode":"event_whenflagclicked","count":1},
3062
- {"opcode":"motion_gotoxy","count":1},
3063
- {"opcode":"motion_changeyby","count":1},
3064
- {"opcode":"operator_random","count":1},
3065
- {"opcode":"motion_xposition","count":2},
3066
- {"opcode":"control_wait","count":1},
3067
- {"opcode":"control_forever","count":1},
3068
- {"opcode":"control_if","count":2},
3069
- {"opcode":"control_stop","count":1},
3070
- {"opcode":"operator_lt","count":1},
3071
- {"opcode":"sensing_touchingobject","count":1},
3072
- #{"opcode":"sensing_touchingobjectmenu","count":1},
3073
- {"opcode":"event_broadcast","count":1},
3074
- {"opcode":"data_setvariableto","count":2},
3075
- {"opcode":"data_showvariable","count":2},
3076
- ]
3077
  pseudo_code="""
3078
- when green flag clicked
3079
- wait (2) sec
3080
- go to x: (pick random -240 to 240) y: (-135)
3081
- set [score v] to (1)
3082
- set [speed v] to (1)
3083
- show variable [score v]
3084
- show variable [speed v]
3085
- forever
3086
- if <((x position)) < (-235)> then
3087
- change y by (x position)
3088
- end
3089
- if <touching [Sprite1 v]?> then
3090
- broadcast [Game Over v]
3091
- stop [all v]
3092
- end
3093
- end
3094
  end
3095
  """
3096
  # print(pseudo_code)
 
277
  "control_stop": {
278
  "block_name": "stop [v]", "block_type": "Control", "block_shape": "Cap Block", "op_code": "control_stop",
279
  "functionality": "Halts all scripts, only the current script, or other scripts within the same sprite. Its shape can dynamically change based on the selected option.",
280
+ "inputs": {}, "fields": {"STOP_OPTION": ["all", None]}, "shadow": False, "topLevel": True, "mutation": {"tagName": "mutation", "children": [], "hasnext": "false"}
281
  },
282
  "control_start_as_clone": {
283
  "block_name": "When I Start as a Clone", "block_type": "Control", "block_shape": "Hat Block", "op_code": "control_start_as_clone",
 
1017
  # [ORDER NO: ]
1018
  # Variable reporter: [score v] or (score) or just "score"
1019
  m_var = re.fullmatch(r"\[([^\]]+)\s*v\]", text)
 
1020
  if m_var:
1021
  var_name = m_var.group(1).strip()
1022
  print("the reportor block variable: ",var_name)
 
1025
 
1026
  # [ORDER NO: ]
1027
  m_paren_var = re.fullmatch(r"\(([^)]+)\)", text)
1028
+ m_cos = re.fullmatch(r"""\(\s*costume\s+(?:\(\s*(.+?)\s*\)|\[\s*([^\]]+?)\s*v\s*\])\s*\)""",text,re.IGNORECASE | re.VERBOSE)
1029
  if m_paren_var and not m_cos:
1030
+ potential = m_paren_var.group(1).strip()
1031
+ # If it's literally “[name v]”, pull out just “name”
1032
+ m_bracket_var = re.fullmatch(r"\[\s*([^\]]+?)\s*v\s*\]", potential)
1033
+ if m_bracket_var: potential = m_bracket_var.group(1).strip()
1034
+ print("the potential_var_name variable:", potential)
1035
+ # Only create a data_variable if it’s not a reporter or a number or contains arithmetic
1036
+ if (potential not in simple_reporters and not re.fullmatch(r"-?\d+(\.\d+)?", potential) and not re.search(r"[+\-*/]", potential)):
1037
+ block_id = _register_block("data_variable",parent_key,True,pick_key_func,all_generated_blocks,fields={"VARIABLE": [potential, None]})
1038
  return {"kind": "block", "block": block_id}
1039
+
1040
  # [ORDER NO: ]
1041
  # List reporter: [my list v]
1042
  m_list_reporter = re.fullmatch(r"\[([^\]]+)\s*v\]", text.strip())
 
1617
  m_not = re.fullmatch(r"\s*(?:<\s*)?not\s+(.+?)(?:\s*>)?\s*", s_lower, re.IGNORECASE)
1618
  if m_not:
1619
  inner = m_not.group(1).strip()
1620
+ print("Boolean NOT--->",m_not.group(1).strip())
1621
  inner_obj = parse_condition(inner, parent_key, pick_key_func, all_generated_blocks)
1622
  bid = _register_block("operator_not", parent_key, True, pick_key_func, all_generated_blocks,
1623
  inputs={"OPERAND": inner_obj})
 
1713
  return {"kind": "block", "block": block_id}
1714
 
1715
  # 5) Touching object: <touching [edge v]?>
1716
+ m_touch = re.fullmatch(r"""\s*<?\s*touching\s*\[\s*(?P<sprite>[^\]]+?)\s*(?:v)?\s*\]\s*\?\s*>?""", s_lower, re.IGNORECASE | re.VERBOSE)
 
 
 
 
 
 
1717
  if m_touch:
1718
  sprite = m_touch.group('sprite').strip()
1719
  val = {'mouse-pointer':'_mouse_', 'edge':'_edge_'}.get(sprite, sprite)
 
1746
  return {"kind": "block", "block": block_id}
1747
 
1748
  # 8) Key pressed: <key [key v] pressed?>
1749
+ # m = re.search(r"key \[([^\]]+)\s*v\] pressed\?", s_lower)
1750
+ # if m:
1751
+ # option = m.group(1).strip()
1752
+ # menu_block_id = _register_block("sensing_keyoptions", parent_key, True, pick_key_func, all_generated_blocks, fields={"KEY_OPTION": [option, None]})
1753
+ # print("<key [key v] pressed?> : ",option)
1754
+ # inputs = {"KEY_OPTION": {"kind": "block", "block": menu_block_id}}
1755
+ # block_id = _register_block("sensing_keypressed", parent_key, True, pick_key_func, all_generated_blocks, inputs=inputs)
1756
+ # all_generated_blocks[menu_block_id]["parent"] = block_id
1757
+ # return {"kind": "block", "block": block_id}
1758
+ m = re.search(r"(?:<)?(?:key\s*)?\[([^\]]+?)\s*v\](?:\s*key)?\s*pressed\?(?:>)?", s_lower, re.IGNORECASE)
1759
  if m:
1760
  option = m.group(1).strip()
1761
  menu_block_id = _register_block("sensing_keyoptions", parent_key, True, pick_key_func, all_generated_blocks, fields={"KEY_OPTION": [option, None]})
1762
+ print("<key [...] pressed?> : ", option)
1763
  inputs = {"KEY_OPTION": {"kind": "block", "block": menu_block_id}}
1764
  block_id = _register_block("sensing_keypressed", parent_key, True, pick_key_func, all_generated_blocks, inputs=inputs)
1765
  all_generated_blocks[menu_block_id]["parent"] = block_id
 
1787
  Order of checks matters: more specific patterns should come before more general ones.
1788
  """
1789
  l = line.lower().strip()
1790
+ print("the line is this:", l)
1791
  # Ignore comments
1792
  if l.startswith("//"): return None, None
1793
 
 
1962
  while i < len(lines):
1963
  raw_line = lines[i]
1964
  stripped_line = raw_line.strip()
1965
+ print("Stripped line here -----1---->", stripped_line)
1966
  # Skip empty lines and comments
1967
  if not stripped_line or stripped_line.startswith("//"):
1968
  i += 1
 
1995
  # Pop the current substack's scope
1996
  popped_indent, popped_owner_key, popped_last_block_in_chain = stack.pop()
1997
  if popped_last_block_in_chain:
1998
+ print("popped_last_block_in_chain is executed here")
1999
  all_generated_blocks[popped_last_block_in_chain]["next"] = None
2000
 
2001
  # If the popped scope had an owner (C-block or procedure definition),
 
2039
  current_scope_indent, current_owner_block_id, last_block_in_current_chain = stack[-1]
2040
 
2041
  # Classify the statement and create the block
2042
+ #stmt_for_parse = stripped_line.rstrip("then").strip()
2043
+ stmt_for_parse = re.sub(r"\bthen\s*$", "", stripped_line, flags=re.IGNORECASE).strip()
2044
+ print("befor the classify hit here: ",stmt_for_parse)
2045
  opcode, ntype = classify(stmt_for_parse)
2046
+ print("the opcode classify: ",opcode)
2047
  if opcode is None: # Should not happen if classify is robust
2048
  i += 1
2049
  continue
 
2243
  if m_item: info["inputs"]["ITEM"] = {"kind": "value", "value": m_item.group(1).strip()}
2244
  elif opcode == "event_whengreaterthan":
2245
  #m = re.search(r">\s*\(\s*(-?\d+(\.\d+)?)\s*\)", stmt_for_parse, re.IGNORECASE)
2246
+ print(stmt_for_parse)
2247
+ m = re.search(r">\s*(?:\(\s*(.*?)\s*\)|([^\s\)]+))", stmt_for_parse, re.IGNORECASE)
2248
+ print("event_whengreaterthan parse",m.group(1).strip())
2249
  #if m: info["inputs"]["VALUE"] = {"kind": "value", "value": float(m.group(1)) if '.' in m.group(1) else int(m.group(1))}
2250
  if m: info["inputs"]["VALUE"] = parse_reporter_or_value(m.group(1).strip(), key, pick_key, all_generated_blocks)
2251
 
 
2348
  m = re.search(r"switch costume to\s*\[([^\]]+)\s*v\]", stmt_for_parse, re.IGNORECASE)
2349
  if m:
2350
  option = m.group(1).strip()
2351
+ print("option at looks_switchcostumeto: ",option)
2352
  menu_block_id = _register_block("looks_costume", key, True, pick_key, all_generated_blocks, fields={"COSTUME": [option, None]})
2353
  info["inputs"]["COSTUME"] = {"kind": "block", "block": menu_block_id}
2354
  elif opcode in ["looks_switchbackdropto", "looks_switchbackdroptowait"]:
 
3066
  #################################################################################################################################################################
3067
 
3068
  initial_opcode_counts = [
3069
+ {
3070
+ "opcode": "event_whenbroadcastreceived",
3071
+ "count": 1
3072
+ },
3073
+ {
3074
+ "opcode": "looks_hide",
3075
+ "count": 1
3076
+ }
3077
+ ]
 
 
 
 
 
 
 
3078
  pseudo_code="""
3079
+ when I receive [Game Over v]
3080
+ hide
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3081
  end
3082
  """
3083
  # print(pseudo_code)