Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. import sys
  2. __tinypy__ = "tinypy" in sys.version
  3. if not __tinypy__:
  4.     from boot import *
  5.     __tinypy__ = False
  6. else:
  7.     __tinypy__ = True
  8.    
  9. def get_ops():
  10.     """ Builds an value <-> opcode name dictionary """
  11.     li = ["EOF","ADD","SUB","MUL","DIV","POW","BITAND","BITOR","CMP","GET", \
  12.           "SET","NUMBER","STRING","GGET","GSET","MOVE","DEF","PASS",  \
  13.           "JUMP","CALL","RETURN","IF","DEBUG","EQ","LE","LT","DICT",  \
  14.           "LIST","NONE","LEN","LINE","PARAMS","IGET","FILE","NAME",   \
  15.           "NE","HAS","RAISE","SETJMP","MOD","LSH","RSH","ITER","DEL", \
  16.           "REGS","BITXOR", "IFN", "NOT", "BITNOT"]
  17.     dic = {}
  18.     for i in li:
  19.         dic[li.index(i)] = i
  20.     return dic
  21.  
  22. def isupper(x):
  23.     return ord(x) >= ord("A") and ord(x) <= ord("Z")
  24.  
  25. def pad(s, n):
  26.     p = ""
  27.     if n < 0:
  28.         m = -n - len(s)
  29.         if m > 0: p = " " * m
  30.         return p + s
  31.     m = n - len(s)
  32.     if m > 0: p = " " * m
  33.     return s + p
  34.  
  35. def funpack(bytes):
  36.     if not __tinypy__:
  37.         import struct
  38.         return struct.unpack("d", bytes)[0]
  39.     def eat(x, bit):
  40.         y = int(x / 2 ** bit)
  41.         x -= y * 2 ** bit
  42.         return x, y
  43.     x = 0
  44.     for i in range(8):
  45.         x += ord(bytes[i]) * 2 ** (i * 8)
  46.     x, sign = eat(x, 63)
  47.     x, exponent = eat(x, 52)
  48.     x, mantissa1 = eat(x, 31)
  49.     x, mantissa2 = eat(x, 0)
  50.     mantissa = mantissa1 * 2 ** 31 + mantissa2
  51.     sign = sign * -2 + 1
  52.     x = sign * 2 ** (exponent - 1023) * (1 + mantissa / 2 ** 52)
  53.     return x
  54.  
  55. def text(x, ip, bc):
  56.     return "".join([chr(c) for c in bc[ip:ip+x]])
  57.  
  58. def trim(x):
  59.     txt = []
  60.     for c in x:
  61.         if ord(c):
  62.             txt.append(c)
  63.     return "".join(txt)
  64.  
  65. def disassemble(bc):    
  66.     bc = [ord(x) for x in bc]
  67.     asmc = []
  68.     ip = 0
  69.     names = get_ops()
  70.     while ip < len(bc):
  71.         i, a, b, c = bc[ip:ip + 4]
  72.         line = ""
  73.         line += pad(names[i], 10) + ":"
  74.         line += " " + pad(str(a), -3)
  75.         line += " " + pad(str(b), -3)
  76.         line += " " + pad(str(c), -3)
  77.         ip += 4
  78.         if names[i] == "LINE":
  79.             n = a * 4
  80.             line += " \"" + text(n,ip,bc) + "\""
  81.             line = trim(line)
  82.             ip += n
  83.         elif names[i] == "STRING":
  84.             n = b * 256 + c
  85.             line += " \"" + text(n,ip,bc) + "\""
  86.             line = trim(line)
  87.             ip += (int(n / 4) + 1) * 4
  88.         elif names[i] == "NUMBER":  
  89.             f = funpack(text(8,ip,bc))
  90.             line += " " + str(f)
  91.             ip += 8
  92.         asmc.append(line)
  93.     asmc = "\n".join(asmc)
  94.     return asmc
  95.    
  96. if __name__ == "__main__":
  97.     bc = load(ARGV[1])
  98.     asmc = disassemble(bc)
  99.     print(asmc)
  100.