# MANTASM - Manta Assembler Sürüm 0.7.2
# 2021
import sys
from pathlib import Path

buyrukListesi = ["YÜKLE", "İYÜKLE", "TOPLA", "İTOPLA", "İÇIKIŞ", "ÇIKIŞ",
                 "ÇIKAR", "İÇIKAR", "KIYASLA", "İKIYASLA", "ATLA", "ATLAS",
                 "VE", "VEYA", "XOR", "GİRİŞ", "YAZ", "OKU", 
                 "ATLAE", "SAĞKAYDIR", "SOLKAYDIR", "TEMİZLE", "ARTIR", "AZALT",
                 "GEÇ", "SONLANDIR"]

# 0: ZX ZY      BBBBBBXXXXYYYYOOOO
# 1: ZX 0x00    BBBBBBXXXXIIIIIIII
# 2: 0x000      BBBBBBIIIIIIIIIIOO
# 3: ZX         BBBBBBXXXXOOOOOOOO
# 4: 0x00       BBBBBBOOOOIIIIIIII
# 5: Temizle, 6: Artır - Azalt, 7: Geç, 8: Sonlandır

# B: Buyruk Kodu, X: ZX Kaydedicisi, Y: ZY Kaydedicisi, O: Önemsiz, I: Sabit

buyruktipListesi = [0, 1, 0, 1, 4, 3, 0, 1, 0, 1, 2, 2,
                    0, 0, 0, 3, 0, 0, 2, 0, 0, 5, 6, 6,
                    7, 8]

buyrukDeğer = ["000001", "000010", "000011", "000100", "000101", "000110",
               "000111", "001000", "001001", "001010", "001011", "001100",
               "001101", "001110", "001111", "010000", "010001", "010010",
               "010011", "010100", "010101", "000010", "000100", "001000",
               "000001", "001011"]

kaydediciListesi = ["Z0", "Z1", "Z2", "Z3", "Z4", "Z5",
                    "Z6", "Z7", "Z8", "Z9", "ZA", "ZB", 
                    "ZC", "ZD", "ZE", "ZF"]

kaydediciDeğer = ["0000", "0001", "0010", "0011", "0100", "0101",
                  "0110", "0111", "1000", "1001", "1010", "1011",
                  "1100", "1101", "1110", "1111"]

satırNumarası = 1 # Okunan dosyanın geçerli satır numarasını tutan değişken tanımlanıyor.
buyrukTipi = 0 # 0 kaydedici buyruk tipi, 1 ivedi buyruk tipi, 2 adres buyruk tipi, 3 tek kaydedicili buyruk tipi, 4 tek sabitli buyruk tipi. 
buyrukSayısı = 0x000 # Progamda bulunan buyruk sayısını sayan değişken. 
hata = False

def buyrukÇevir(buyruk):
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    indeks = buyrukListesi.index(buyruk) # Buyruğun listedeki kaçıncı eleman olduğu öğreniliyor.
    dosyaÇıkış.write(buyrukDeğer[indeks]) # Değer tablosuna göre çevriliyor.
    dosyaÇıkış.close()

def kaydediciÇevir(kaydedici):
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    indeks = kaydediciListesi.index(kaydedici)
    dosyaÇıkış.write(kaydediciDeğer[indeks])
    dosyaÇıkış.close()

def değerÇevir(değer):
    global hata
    çevrilenDeğer = int(değer,16)
    if (çevrilenDeğer > 255): # !
        print("Çevirici bir hatayla karşılaştı. (120)\nSatır {0}, Sabit {1} değeri 0xFF sayısndan büyük olamaz.".format(int(satırNumarası), satır[2])) 
        hata = True
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(str('{0:08b}'.format(çevrilenDeğer)))
    dosyaÇıkış.close()

def adresÇevir(adres):
    global hata
    çevrilenAdres = int(adres, 16)
    if (çevrilenAdres > 1023): # !
        print("Çevirici bir hatayla karşılaştı. (130)\nSatır {0}, Program belleği adresi {1}, 0x3FF sayısından büyük olamaz.".format(int(satırNumarası), satır[1]))     
        hata = True
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(str('{0:010b}'.format(çevrilenAdres)))
    dosyaÇıkış.close()

def sıfırEkle(çarpan):
    sıfırlar = "0" * çarpan
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(sıfırlar)
    dosyaÇıkış.close()

def satırSonlandır():
    global buyrukSayısı
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write("\n")
    buyrukSayısı += 1

def tipBul(buyruk):
    indeks = buyrukListesi.index(buyruk)
    return buyruktipListesi[indeks]

def kaydediciHatası(satır, kaydedici):
    print("Çevirici bir hatayla karşılaştı. (110)\nSatır {0}, Geçersiz kaydedici ismi: {1}".format(int(satır), kaydedici))

if len(sys.argv) != 2: 
    print ("Kullanım: MANTASM [dosya yolu]dosya ismi") 
    sys.exit()

print("\n   __  ______   _  ___________   ______  ___\n  /  |/  / _ | / |/ /_  __/ _ | / __/  |/  /\n / /|_/ / __ |/    / / / / __ |_\ \/ /|_/ / \n/_/  /_/_/ |_/_/|_/ /_/ /_/ |_/___/_/  /_/  \n")
print("MANTA ASSEMBLER Sürüm 0.7.2\nİşlem başlatılıyor...")

try:
    dosyaGiriş = open(sys.argv[1], 'r', encoding = 'utf8') # Manta Assembly dosyası
    okunan = dosyaGiriş.read()
except:
    print("Çevirici bir hatayla karşılaştı. (80)\n{0} dosyası okunamadı.\nİşlem başarısız.".format(sys.argv[1]))
    sys.exit()

dosyaİsmi = sys.argv[1]
yenidosya = Path(dosyaİsmi).stem + ".mpd"

try:
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8') # Manta program dosyası
    dosyaÇıkış.close()
except:
    print("Çevirici bir hatayla karşılaştı. (90)\n{0} dosyası oluşturulamadı.\nİşlem başarısız.".format(yenidosya))
    sys.exit()

bölünmüş = okunan.split("\n") # Satırlar ayrılıyor.

for i in range(0, len(bölünmüş)):
    satır = bölünmüş[i].split() # \n'e kadar çalışacak. 
    if len(satır) > 0:
        if satır[0] in buyrukListesi: # Buyruk bulundu.
            #print("-Rastlanan buyruk: %s" %(satır[0]))
            buyrukÇevir(satır[0])
            buyrukTipi = tipBul(satır[0])
            if buyrukTipi == 0: # ZX, ZY
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                if satır[2] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[2]))
                    kaydediciÇevir(satır[2])
                    sıfırEkle(4)
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[2])
                    hata = True
                    break
                
            elif buyrukTipi == 1: # ZX, 0x00
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                #print("-Rastlanan değer: %s" %(satır[2]))
                değerÇevir(satır[2])
                if hata == True:
                    break
                satırSonlandır()
                
            elif buyrukTipi == 2: # 0x000
                #print("-Rastlanan adres: %s"%(satır[1]))
                adresÇevir(satır[1])
                if hata == True:
                    break
                sıfırEkle(2)
                satırSonlandır()
                
            elif buyrukTipi == 3: # 0xZX
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                    sıfırEkle(8)
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                
            elif buyrukTipi == 4: # 0x00
                sıfırEkle(4)
                değerÇevir(satır[1])
                if hata == True:
                    break
                satırSonlandır()

            elif buyrukTipi == 5: # Temizle sözde buyruğu
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                    değerÇevir("0x00")
                    if hata == True:
                        break
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                
            elif buyrukTipi == 6: # Artır - Azalt sözde buyruğu
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                değerÇevir("0x01")
                if hata == True:
                    break
                satırSonlandır()

            elif buyrukTipi == 7: # Geç sözde buyruğu
                sıfırEkle(12)
                satırSonlandır()

            elif buyrukTipi == 8: # Sonlandır sözde buyruğu
                adresÇevir(str(buyrukSayısı + 1))
                sıfırEkle(2)
                satırSonlandır()
                buyrukÇevir("ATLA")
                adresÇevir(str(buyrukSayısı - 1))
                sıfırEkle(2)
                satırSonlandır()

        elif satır[0] == "*": # Yorum karakteri okundu ise.
            pass

        else: # Okunan karakter, buyruk listesinde yok ise.
            print("Çevirici bir hatayla karşılaştı. (100)\nSatır {0}, Beklenmeyen ifade: {1}".format(int(satırNumarası), satır[0]))
            hata = True
            break
    else:
        pass
    satırNumarası += 1

if hata == True:
    print("İşlem başarısız.")
else:
    if buyrukSayısı <= 1024:
        kaplananAlan = (100 * buyrukSayısı) / 1024
        kaplananAlan = round(kaplananAlan, 2)
        print("Program belleğinin %{0} kadarı kullanıldı.".format(kaplananAlan))
    else:
        print("Uyarı: Program belleği kapasitesi aşıldı.")
    print("Çevirme işlemi tamamlandı.")

# MANTASM - Manta Assembler Sürüm 0.7.2
# 2021
import sys
from pathlib import Path

buyrukListesi = ["YÜKLE", "İYÜKLE", "TOPLA", "İTOPLA", "İÇIKIŞ", "ÇIKIŞ",
                 "ÇIKAR", "İÇIKAR", "KIYASLA", "İKIYASLA", "ATLA", "ATLAS",
                 "VE", "VEYA", "XOR", "GİRİŞ", "YAZ", "OKU", 
                 "ATLAE", "SAĞKAYDIR", "SOLKAYDIR", "TEMİZLE", "ARTIR", "AZALT",
                 "GEÇ", "SONLANDIR"]

# 0: ZX ZY      BBBBBBXXXXYYYYOOOO
# 1: ZX 0x00    BBBBBBXXXXIIIIIIII
# 2: 0x000      BBBBBBIIIIIIIIIIOO
# 3: ZX         BBBBBBXXXXOOOOOOOO
# 4: 0x00       BBBBBBOOOOIIIIIIII
# 5: Temizle, 6: Artır - Azalt, 7: Geç, 8: Sonlandır

# B: Buyruk Kodu, X: ZX Kaydedicisi, Y: ZY Kaydedicisi, O: Önemsiz, I: Sabit

buyruktipListesi = [0, 1, 0, 1, 4, 3, 0, 1, 0, 1, 2, 2,
                    0, 0, 0, 3, 0, 0, 2, 0, 0, 5, 6, 6,
                    7, 8]

buyrukDeğer = ["000001", "000010", "000011", "000100", "000101", "000110",
               "000111", "001000", "001001", "001010", "001011", "001100",
               "001101", "001110", "001111", "010000", "010001", "010010",
               "010011", "010100", "010101", "000010", "000100", "001000",
               "000001", "001011"]

kaydediciListesi = ["Z0", "Z1", "Z2", "Z3", "Z4", "Z5",
                    "Z6", "Z7", "Z8", "Z9", "ZA", "ZB", 
                    "ZC", "ZD", "ZE", "ZF"]

kaydediciDeğer = ["0000", "0001", "0010", "0011", "0100", "0101",
                  "0110", "0111", "1000", "1001", "1010", "1011",
                  "1100", "1101", "1110", "1111"]

satırNumarası = 1 # Okunan dosyanın geçerli satır numarasını tutan değişken tanımlanıyor.
buyrukTipi = 0 # 0 kaydedici buyruk tipi, 1 ivedi buyruk tipi, 2 adres buyruk tipi, 3 tek kaydedicili buyruk tipi, 4 tek sabitli buyruk tipi. 
buyrukSayısı = 0x000 # Progamda bulunan buyruk sayısını sayan değişken. 
hata = False

def buyrukÇevir(buyruk):
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    indeks = buyrukListesi.index(buyruk) # Buyruğun listedeki kaçıncı eleman olduğu öğreniliyor.
    dosyaÇıkış.write(buyrukDeğer[indeks]) # Değer tablosuna göre çevriliyor.
    dosyaÇıkış.close()

def kaydediciÇevir(kaydedici):
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    indeks = kaydediciListesi.index(kaydedici)
    dosyaÇıkış.write(kaydediciDeğer[indeks])
    dosyaÇıkış.close()

def değerÇevir(değer):
    global hata
    çevrilenDeğer = int(değer,16)
    if (çevrilenDeğer > 255): # !
        print("Çevirici bir hatayla karşılaştı. (120)\nSatır {0}, Sabit {1} değeri 0xFF sayısndan büyük olamaz.".format(int(satırNumarası), satır[2])) 
        hata = True
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(str('{0:08b}'.format(çevrilenDeğer)))
    dosyaÇıkış.close()

def adresÇevir(adres):
    global hata
    çevrilenAdres = int(adres, 16)
    if (çevrilenAdres > 1023): # !
        print("Çevirici bir hatayla karşılaştı. (130)\nSatır {0}, Program belleği adresi {1}, 0x3FF sayısından büyük olamaz.".format(int(satırNumarası), satır[1]))     
        hata = True
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(str('{0:010b}'.format(çevrilenAdres)))
    dosyaÇıkış.close()

def sıfırEkle(çarpan):
    sıfırlar = "0" * çarpan
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write(sıfırlar)
    dosyaÇıkış.close()

def satırSonlandır():
    global buyrukSayısı
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8')
    dosyaÇıkış.write("\n")
    buyrukSayısı += 1

def tipBul(buyruk):
    indeks = buyrukListesi.index(buyruk)
    return buyruktipListesi[indeks]

def kaydediciHatası(satır, kaydedici):
    print("Çevirici bir hatayla karşılaştı. (110)\nSatır {0}, Geçersiz kaydedici ismi: {1}".format(int(satır), kaydedici))

if len(sys.argv) != 2: 
    print ("Kullanım: MANTASM [dosya yolu]dosya ismi") 
    sys.exit()

print("\n   __  ______   _  ___________   ______  ___\n  /  |/  / _ | / |/ /_  __/ _ | / __/  |/  /\n / /|_/ / __ |/    / / / / __ |_\ \/ /|_/ / \n/_/  /_/_/ |_/_/|_/ /_/ /_/ |_/___/_/  /_/  \n")
print("MANTA ASSEMBLER Sürüm 0.7.2\nİşlem başlatılıyor...")

try:
    dosyaGiriş = open(sys.argv[1], 'r', encoding = 'utf8') # Manta Assembly dosyası
    okunan = dosyaGiriş.read()
except:
    print("Çevirici bir hatayla karşılaştı. (80)\n{0} dosyası okunamadı.\nİşlem başarısız.".format(sys.argv[1]))
    sys.exit()

dosyaİsmi = sys.argv[1]
yenidosya = Path(dosyaİsmi).stem + ".mpd"

try:
    dosyaÇıkış = open(yenidosya, 'a', encoding = 'utf8') # Manta program dosyası
    dosyaÇıkış.close()
except:
    print("Çevirici bir hatayla karşılaştı. (90)\n{0} dosyası oluşturulamadı.\nİşlem başarısız.".format(yenidosya))
    sys.exit()

bölünmüş = okunan.split("\n") # Satırlar ayrılıyor.

for i in range(0, len(bölünmüş)):
    satır = bölünmüş[i].split() # \n'e kadar çalışacak. 
    if len(satır) > 0:
        if satır[0] in buyrukListesi: # Buyruk bulundu.
            #print("-Rastlanan buyruk: %s" %(satır[0]))
            buyrukÇevir(satır[0])
            buyrukTipi = tipBul(satır[0])
            if buyrukTipi == 0: # ZX, ZY
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                if satır[2] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[2]))
                    kaydediciÇevir(satır[2])
                    sıfırEkle(4)
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[2])
                    hata = True
                    break
                
            elif buyrukTipi == 1: # ZX, 0x00
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                #print("-Rastlanan değer: %s" %(satır[2]))
                değerÇevir(satır[2])
                if hata == True:
                    break
                satırSonlandır()
                
            elif buyrukTipi == 2: # 0x000
                #print("-Rastlanan adres: %s"%(satır[1]))
                adresÇevir(satır[1])
                if hata == True:
                    break
                sıfırEkle(2)
                satırSonlandır()
                
            elif buyrukTipi == 3: # 0xZX
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                    sıfırEkle(8)
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                
            elif buyrukTipi == 4: # 0x00
                sıfırEkle(4)
                değerÇevir(satır[1])
                if hata == True:
                    break
                satırSonlandır()

            elif buyrukTipi == 5: # Temizle sözde buyruğu
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                    değerÇevir("0x00")
                    if hata == True:
                        break
                    satırSonlandır()
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                
            elif buyrukTipi == 6: # Artır - Azalt sözde buyruğu
                if satır[1] in kaydediciListesi:
                    #print("-Rastlanan kaydedici: %s" %(satır[1]))
                    kaydediciÇevir(satır[1])
                else:
                    kaydediciHatası(satırNumarası, satır[1])
                    hata = True
                    break
                değerÇevir("0x01")
                if hata == True:
                    break
                satırSonlandır()

            elif buyrukTipi == 7: # Geç sözde buyruğu
                sıfırEkle(12)
                satırSonlandır()

            elif buyrukTipi == 8: # Sonlandır sözde buyruğu
                adresÇevir(str(buyrukSayısı + 1))
                sıfırEkle(2)
                satırSonlandır()
                buyrukÇevir("ATLA")
                adresÇevir(str(buyrukSayısı - 1))
                sıfırEkle(2)
                satırSonlandır()

        elif satır[0] == "*": # Yorum karakteri okundu ise.
            pass

        else: # Okunan karakter, buyruk listesinde yok ise.
            print("Çevirici bir hatayla karşılaştı. (100)\nSatır {0}, Beklenmeyen ifade: {1}".format(int(satırNumarası), satır[0]))
            hata = True
            break
    else:
        pass
    satırNumarası += 1

if hata == True:
    print("İşlem başarısız.")
else:
    if buyrukSayısı <= 1024:
        kaplananAlan = (100 * buyrukSayısı) / 1024
        kaplananAlan = round(kaplananAlan, 2)
        print("Program belleğinin %{0} kadarı kullanıldı.".format(kaplananAlan))
    else:
        print("Uyarı: Program belleği kapasitesi aşıldı.")
    print("Çevirme işlemi tamamlandı.")

# MANTASM - Manta Assembler Sürüm 0.7.2 # 2021 # 0: ZX ZY      BBBBBBXXXXYYYYOOOO # 1: ZX 0x00    BBBBBBXXXXIIIIIIII # 2: 0x000      BBBBBBIIIIIIIIIIOO # 3: ZX         BBBBBBXXXXOOOOOOOO # 4: 0x00       BBBBBBOOOOIIIIIIII # 5: Temizle, 6: Artır - Azalt, 7: Geç, 8: Sonlandır # B: Buyruk Kodu, X: ZX Kaydedicisi, Y: ZY Kaydedicisi, O: Önemsiz, I: Sabit # Okunan dosyanın geçerli satır numarasını tutan değişken tanımlanıyor. # 0 kaydedici buyruk tipi, 1 ivedi buyruk tipi, 2 adres buyruk tipi, 3 tek kaydedicili buyruk tipi, 4 tek sabitli buyruk tipi. # Progamda bulunan buyruk sayısını sayan değişken. # Buyruğun listedeki kaçıncı eleman olduğu öğreniliyor. # Değer tablosuna göre çevriliyor. # ! # ! # Manta Assembly dosyası # Manta program dosyası # Satırlar ayrılıyor. # \n'e kadar çalışacak. # Buyruk bulundu. #print("-Rastlanan buyruk: %s" %(satır[0])) # ZX, ZY #print("-Rastlanan kaydedici: %s" %(satır[1])) #print("-Rastlanan kaydedici: %s" %(satır[2])) # ZX, 0x00 #print("-Rastlanan kaydedici: %s" %(satır[1])) #print("-Rastlanan değer: %s" %(satır[2])) # 0x000 #print("-Rastlanan adres: %s"%(satır[1])) # 0xZX #print("-Rastlanan kaydedici: %s" %(satır[1])) # 0x00 # Temizle sözde buyruğu #print("-Rastlanan kaydedici: %s" %(satır[1])) # Artır - Azalt sözde buyruğu #print("-Rastlanan kaydedici: %s" %(satır[1])) # Geç sözde buyruğu # Sonlandır sözde buyruğu # Yorum karakteri okundu ise. # Okunan karakter, buyruk listesinde yok ise.