Commits

Martin Haye  committed f30f3d7

Lots of improvements and fixes.

  • Participants
  • Parent commits 80245ea

Comments (0)

Files changed (2)

File AsbFilter.py

 
 referencedLines = set()
 firstRefdLine = None
+lineSubMap = {}
 
 ##############################################################################
 class TransformError(Exception):
     
 
 ##############################################################################
+def abortTransform(message):
+  """ Raises an exception that aborts the transformation. """
+  
+  raise TransformError(message)
+  
+      
+##############################################################################
 class BasicLine:
   """ Holds information about one line of the BASIC program. """
   
 
 
 ##############################################################################
+def calcLineMark(fromLine, lineNum):
+  """ Determine the shorthand version of a line, if any. """
+
+  if not lineNum: return lineNum
+  if not int(lineNum) in lineSubMap: return lineNum
+  lineNum = int(lineNum)
+  if fromLine >= 0 and lineSubMap[fromLine] != lineSubMap[lineNum]:
+    abortTransform("Illegal ref to %s inside another sub from line %d" \
+                   % (lineNum, fromLine))
+  return "+" + str(lineNum - lineSubMap[lineNum])
+
+
+##############################################################################
 def transformForEditing(lines):
   """ Perform transformations to make the BASIC program easy to edit. This
       makes it un-pasteable however, and it needs to be transformed back
         referencedLines.add(lineNum)
         if not firstRefdLine or lineNum < firstRefdLine:
           firstRefdLine = lineNum
+          
+  # Determine where the subroutine boundaries are, and assign each line
+  # to a sub when possible
+  curSub = None
+  for line in lines:
+    found = False
+    for piece in line.pieces:
+      if re.match("REM\W+SUB", piece, re.IGNORECASE):
+        found = True
+      elif len(piece.strip()) > 0:
+        break
+    if found:
+      curSub = line.lineNum
+    elif curSub >= 0 and line.lineNum and line.lineNum > curSub:
+      lineSubMap[line.lineNum] = curSub
   
-  # Remove line numbers that aren't referenced
+  # Replace line number references within a sub
   for line in lines:
+    newPieces = []
+    for piece in line.pieces:
+      m = re.match("(.*)(THEN|GOTO|GOSUB)(.*)", piece, re.IGNORECASE)
+      if m:
+        piece = m.group(1) + m.group(2) + \
+                re.sub("\d+", lambda m: calcLineMark(line.lineNum, m.group(0)), m.group(3))
+      newPieces.append(piece)
+    line.pieces = newPieces
+    
     if line.lineNum > firstRefdLine and not line.lineNum in referencedLines:
       line.lineNum = ""
       if line.pieces and line.pieces[0].strip() == "":
         del line.pieces[0]
-  
+    else:
+      line.lineNum = calcLineMark(None, line.lineNum)
+      
   # Add a line so we can tell the transformation needs to be reversed.
   if lines[0].origText.strip().upper() == "NEW":
     lines.pop(0)
 
 
 ##############################################################################
-def abortTransform(message):
-  """ Raises an exception that aborts the transformation. """
-  
-  raise TransformError(message)
-  
-      
-##############################################################################
 def flushBlock(block, startLine, endLine, out):
   """ Auto-number a block of lines with the given start and end constraints. """
   

File Structris.asb

 60 POKE KS,0
 
 100 REM SUB MAIN LOOP
-    105 ON M + 1 GOSUB 400,500,600,700,800
+    105 ON M + 1 GOSUB 400,500,900,700,800
     110 COLOR= 0: PLOT CX,CY
     115 CALL 641: REM SCROLL
     120 IF PEEK(8) > 0 THEN GOSUB 300
     140 GOSUB 200
     145 COLOR= 15: PLOT CX,CY
     150 GOTO 100
-    
+
 200 REM SUB KEYBOARD PROCESSING
     205 K = PEEK(KB)
     210 IF K < 200 THEN RETURN
     310 RC = RC + 1: IF RC < 3 THEN RETURN
     320 RC = 0:HB = HB + 1
     330 RD = RD + 1
-    350 VTAB 22: HTAB 13
-    355 PRINT "CLEARED ";RD;"/";RG
-    360 IF RD < RG THEN RETURN
-    370 GOTO 3300: REM LVL UP
+    340 GOSUB 370
+    350 IF RD >= RG THEN GOSUB 3300
+    360 RETURN
+
+370 REM SUB PRINT NUM CLEARED
+    380 VTAB 22: HTAB 13
+    385 PRINT "CLEARED ";RD;"/";RG
+    390 RETURN
 
 400 REM SUB PICK X COORD
     405 IF X < 0 THEN X = INT((CX - OX) / 2) + 1
     570 IF HL < 0 THEN HL = 3
     580 M = M + 1: RETURN
 
-600 REM SUB CHOOSE SHAPE
-    610 M = M + 1
-    620 ON HL * 4 + HR + 1 GOTO 1001,1010,1020,1030,1040,1050,1060,1070,1080,1090,1100,1110,1120,1130,1140,1150
-    630 STOP : REM IMPOSSIBLE
-
 700 REM SUB APPLY CHOSEN COORD
     705 H(X - 1) = H(X - 1) + BL
     710 H(X) = H(X) + B0
     870 IF BL + B0 + BR = 0 THEN X = - 99:M = 0
     875 RETURN
 
-1000 REM SUB SHAPE PICKER
-    1001 REM 000
-    1002 ON RND(1) * 4 + 1 GOTO 1200,1300,1530,1620
+900 REM SUB CHOOSE SHAPE
+    910 M = M + 1
+    920 ON HL * 4 + HR + 1 GOTO 1000,1010,1020,1030,1040,1050,1060,1070,1080,1090,1100,1110,1120,1130,1140,1150
+    930 STOP : REM IMPOSSIBLE
+
+    1000 REM 000
+    1001 ON RND(1) * 4 + 1 GOTO 1200,1300,1530,1620
     1010 REM 001
     1011 GOTO 1440
     1020 REM 002
     3150 RG = 5 + LV * 2:RD = 0:RC = 0
     3155 HOME
     3160 VTAB 21: HTAB 16: PRINT "LEVEL ";LV
-    3170 GOTO 350
+    3170 GOSUB 370
+    3180 RETURN
 
 3200 REM SUB DRAW FIRST LVL BORDERS
     3202 GR : HOME
     3205 COLOR= 5: VLIN 0,H * 2 + 1 AT OX - 1: VLIN 0,H * 2 + 1 AT 40 - OX
+    3210 GOSUB 3250: RETURN
+
+3250 REM SUB GENERAL LEVEL BORDERS
     3210 COLOR= 4: HLIN OX,39 - OX AT H * 2: HLIN OX,39 - OX AT H * 2 + 1
     3215 COLOR= 5: FOR I = OX TO 38 - OX STEP 2: PLOT I,H * 2: PLOT I + 1,H * 2 + 1: NEXT
     3220 RETURN
     3340 GOSUB 3600
     3350 LV = LV + 1: GOSUB 3100
     3352 IF LV = 11 THEN 3500
-    3355 GOSUB 3210
+    3355 GOSUB 3250
     3360 COLOR= 5: VLIN 0,H * 2 + 2 AT OX - 1: VLIN 0,H * 2 + 2 AT 40 - OX
     3365 COLOR= 0: VLIN 0,H * 2 + 1 AT OX - 2: VLIN 0,H * 2 + 1 AT 41 - OX
     3370 RETURN