asm2s のソースコード

#!
# coding: utf-8
# Copyright (C) 2016 TOPS SYSTEMS
### @file  asm2s.py
### @brief ASM format source file to S format source file convertor
###
### ASM形式(ただしQVPの記述のために用いられている範囲)のソースファイルを
### topsqvp-elf_as形式のソーフファイルに変換するコンバータ
### ①行を読み取ってラベル、命令、引数にパースする
### ②疑似命令やマクロ命令など互換性のない部分を変換する
### ③機械的に変換できない部分についてはWARNING!としてコメントアウトする
### 
### 読み取り途中でコメントを検出したならばコメント文字を変換し行末まで飛ばす。
###
### Contact: izumida@topscom.co.jp
###
### @author: M.Izumida
### @date: October 24, 2016
###
## v01r01 Newly created
## v01r02 v01r02 INC file support
##
# Written for Python 2.7 (NOT FOR 3.x)
#=======================================================================
# インポート宣言
from __future__ import division
import sys
import re
import argparse
import os
from datetime import datetime
#=======================================================================
# バージョン文字列
versionSTR = "asm2s.py v01r02 Tops Systems (pgm by mpi)"
#=======================================================================
# 共通サブルーチン
#-------------------------------------------------------------------
def errPrint(mes):
    """errPrint.

    エラー出力へのメッセージ表示
    後の始末はその後で別に書くこと
    """
    sys.stderr.write(mes)
    sys.stderr.write('\n')

#-------------------------------------------------------------------
def stdExceptionHandler(mes):
    """standard Exception Handler.

    エラーメッセージを送出し、デバッグのための情報を出力する
    """
    errPrint("Exception Captured: " + str(mes))
    errPrint("0:" + str(sys.exc_info()[0]))
    errPrint("1:" + str(sys.exc_info()[1]))
    errPrint("2:" + str(sys.exc_info()[2]))
#-------------------------------------------------------------------
def tryIntParse(st, dval, radix=10):
    """try Parse string to Integer

    文字列stをパースして整数化できれば値を返す、できなければデフォルト値dvalを返す
    """
    try:
        work = int(st, radix)
    except:
        return dval
    return work

#-------------------------------------------------------------------
def repExt(fname, newext):
    """Relpace Extension

    fnameの拡張子部分をnewextでリプレースした文字列を返す
    """
    tempName, ext = os.path.splitext(os.path.basename(fname))
    return tempName + newext

#=======================================================================
# ASMファイルリーダクラス
[ドキュメント]class asmReader: """ASM File Reader Class. ASMファイルを読み取ってパースするクラス """ #-------------------------------------------------------------------- def __init__(self, fnam, oCls, opt): """ASM File Reader Constructor コンストラクタ """ self.asmFname = fnam # パースするASMファイルへのパス self.outClass = oCls # 出力先となるクラス(通常はsWriterクラス) self.opt = opt # オプションパラメータ #バッファ self.lineBuffer = "" # 行一時バッファ self.lineMax = 0 # 行一時バッファ文字数 self.linePos = 0 # 行内ポインタ #デバッグ self.debug = False self.verbose = False #--------------------------------------------------------------------
[ドキュメント] def read(self): """read method ファイルから行をリードして処理するメソッド """ nLine = 1 try: with open(self.asmFname, 'r') as f: for line in f: if self.rLine(line): break nLine += 1 except: stdExceptionHandler("ERROR: in file reading = " + self.asmFname + " line#=" + str(nLine)) return False return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin): """Read Line method 読み取った1行を処理するメソッド 常にFalseを返す。 (エラーが定義されたらTrueを返す) """ if self.verbose: print lin if self.debug: self.outClass.writeLine(lin.rstrip()) self.setLine(lin) self.outClass.initLineParser() cnt = self.skipSPACE() tkn = self.getTOKEN() while tkn[0] != 0: if tkn[0]==999: self.outClass.writeToken(tkn) return True if (tkn[0]==100) and (cnt == 0): tkn[0] = 200 if not self.outClass.writeToken(tkn): return True cnt = self.skipSPACE() cnt = 1 tkn = self.getTOKEN() self.outClass.finishLineParser() return False
#--------------------------------------------------------------------
[ドキュメント] def setLine(self, lin): """Set Line to line buffer 1行バッファを初期化するメソッド """ self.lineBuffer = lin self.lineMax = len(lin) self.linePos = 0 return False
#--------------------------------------------------------------------
[ドキュメント] def getCHR(self): """LINE BUFFER, get char 1行バッファから1文字読み出すメソッド """ if self.linePos < self.lineMax: temp = self.lineBuffer[self.linePos] self.linePos += 1 return temp return None
#--------------------------------------------------------------------
[ドキュメント] def backCHR(self): """LINE BUFFER, back char 1行バッファに1文字戻すメソッド """ if self.linePos > 0: self.linePos -= 1
#--------------------------------------------------------------------
[ドキュメント] def skipSPACE(self): """LINE BUFFER, skip space 空白文字とタブを読み飛ばすメソッド。読み飛ばした空白文字数を返す。 """ counter = 0 while self.linePos < self.lineMax: if (self.lineBuffer[self.linePos] == " ") or (self.lineBuffer[self.linePos] == "\t"): self.linePos += 1 counter += 1 else: break return counter
#--------------------------------------------------------------------
[ドキュメント] def getTOKEN(self): """LINE BUFFER, get token 1行バッファの現在ポジションから1トークン読み出すメソッド 空白文字の読み飛ばしはしない 現在ポジションが行末に達していたら"EOL"を返す。 0, EOL 1, COMMENT 2, { 3, } 4, [ 5, ] 6, + 7, - 8, * 9, / 10, < 11, > 12, << 13, >> 14, <= 15, >= 16, == 17, != 18, : 19, $ 20, , 21, % 22, & 23, | 99, "string" 100, ID 200, LABEL 999, ERROR-Message """ token = [0, "EOL"] temp = self.getCHR() workStr = "" if (temp is None) or (temp == "\n") or (temp == "\r"): return token if temp == ";": while self.linePos < self.lineMax: #行末までの文字列をコメントとして転送 temp = self.getCHR() if (temp is None) or (temp == "\n") or (temp == "\r"): return [1, workStr] workStr += temp if temp == "{": return [2, "{"] if temp == "}": return [3, "}"] if temp == "[": return [4, "["] if temp == "]": return [5, "]"] if temp == "+": return [6, "+"] if temp == "-": return [7, "-"] if temp == "*": return [8, "*"] if temp == "/": return [9, "/"] if temp == "<": nxt = self.getCHR() if nxt == "<": return [12, "<<"] if nxt == "=": return [14, "<="] self.backCHR() return [10, "<"] if temp == ">": nxt = self.getCHR() if nxt == ">": return [13, ">>"] if nxt == "=": return [15, ">="] self.backCHR() return [11, ">>"] if temp == "=": nxt = self.getCHR() if nxt == "=": return [16, "=="] return [999, "ERROR, operator == expected."] if temp == "!": nxt = self.getCHR() if nxt == "=": return [17, "!="] return [999, "ERROR, operator != expected."] if temp == ":": return [18, ":"] if temp == "$": return [19, "$"] if temp == ",": return [20, ","] if temp == "%": return [21, "%"] if temp == "&": return [22, "&"] if temp == "|": return [23, "|"] if temp == '"': if self.debug: sys.stderr.write("\nSTRING>>>") while self.linePos < self.lineMax: temp = self.getCHR() if temp == '"': return [99, workStr] if (temp is None) or (temp == "\n") or (temp == "\r"): return [999, "ERROR, unexpected string end."] else: workStr += temp if self.debug: sys.stderr.write(temp) if self.debug: sys.stderr.write("\nID>>>") while self.linePos < self.lineMax: if self.debug: sys.stderr.write(temp) if temp.isalnum() or (temp == "_") or (temp == "."): workStr += temp temp = self.getCHR() else: self.backCHR() break if len(workStr) == 0: return [999, "ERROR, unknown token charactor >" + temp + "<"] return [100, workStr.lower()] return None
#======================================================================= # gas形式ソースファイルライタクラス
[ドキュメント]class gasWriter: """GAS Writer Class. asmReaderのパース結果を解釈し、gas形式に変換してファイルに書くクラス """ #-------------------------------------------------------------------- def __init__(self, ofnam, incmode): """debugging Writer Constructor コンストラクタ """ self.oFname = ofnam self.inc = incmode # 一次保存用バッファ self.bufList = [] self.writePredef() # 行パース用 # 0:LABEL/FirstID/# 1:":"/FirstID 2:FirstID/# 3:Second以降のID待ち 9: 行末 self.initLineParser() self.forceComment = False #以降の行でコメント化を強制する。復帰は明示キーワードかself.release self.release = False #1行コメント化したら復帰キーワード検出なしに復帰 self.ifNest = 0 #生きているIF疑似命令のネストカウンタ # マクロ定義用 self.convMacroArgs = False self.macroArgs = [] # EQU解決用 self.equKEY = "" self.equDic = dict() # コンバージョンエラーカウンタ self.numWarning = 0 self.numError = 0 self.sanitized = 0 # デバッグ self.debug = False self.verbose = False #--------------------------------------------------------------------
[ドキュメント] def save(self): """buffer Writer バッファのライタ. 書き込み成功すれば真を返す。 """ if self.ifNest == 1: self.writeLine(".endif") elif self.ifNest > 1: self.writeLine("# WARNING!-TOO-MANY-OPEN-IF") self.numWarning += 1 self.writeLine("# of ERROR: " + str(self.numError)) self.writeLine("# of WARNING: " + str(self.numWarning)) self.writeLine("# of SANITIZED: " + str(self.sanitized)) try: with open(self.oFname, 'w') as f: for lin in self.bufList: f.write(lin) f.write("\n") except: stdExceptionHandler("Error: writing gas source file = " + self.oFname) return False return True
#--------------------------------------------------------------------
[ドキュメント] def writeLine(self, lin, opt=False): """write line to buffer 行を直接バッファへ書き込むためのメソッド. opt=Trueなら行コメントとする """ if opt: lin = "#" + lin self.bufList.append(lin) return
#--------------------------------------------------------------------
[ドキュメント] def initLineParser(self): """initialize line parser 行パーサを初期化するメソッド. """ self.linStat = 0 self.linLabel = "" self.linID1 = "" self.linTemp = "" self.argOpt = [0, 0] # [numArg, opt] self.macroPending = False self.listArgP = False self.equFlag = False self.fifoFlag = False self.INCL = False
#--------------------------------------------------------------------
[ドキュメント] def finishLineParser(self): """finish line parser 行パーサを完了し、1行出力するメソッド. """ if self.forceComment: self.writeLine(self.linTemp, True) if self.release: self.forceComment = False self.release = False else: self.writeLine(self.linTemp)
#--------------------------------------------------------------------
[ドキュメント] def writeToken(self, tkn): """write Token to buffer トークンをバッファへ書き込むためのメソッド. 書き込みトークンが予想外のものであれば偽を返す。 """ if self.debug: return self.writeRawToken(tkn) else: return self.lineParser(tkn)
#--------------------------------------------------------------------
[ドキュメント] def lineParser(self, tkn): """line parser 行パーサ """ #if self.verbose: # print tkn[0], tkn[1] if self.linStat == 0: if tkn[0] == 1: #コメント self.linTemp += "# " + tkn[1] self.linStat = 9 elif tkn[0] == 200: #ラベル self.linLabel = tkn[1] self.linStat = 1 elif tkn[0] == 100: #1st ID self.linID1 = tkn[1] self.checkID1() self.linStat = 3 else: return False elif self.linStat == 1: if tkn[0] == 18: #: self.linTemp += self.linLabel + ": " self.linStat = 2 elif tkn[0] == 100: #1st ID self.linID1 = tkn[1] self.checkLabelID1() self.linStat = 3 else: return False elif self.linStat == 2: if tkn[0] == 1: #コメント self.linTemp += " # " + tkn[1] self.linStat = 9 elif tkn[0] == 100: #1st ID self.linID1 = tkn[1] self.checkID1() self.linStat = 3 else: return False elif self.linStat == 3: if tkn[0] == 1: #コメント self.linTemp += " # " + tkn[1] self.linStat = 9 else: self.proccessARG(tkn) #引数の解釈 else: self.writeLine("Error : TOKEN found after valid line end.", True) self.writeRawToken(tkn) self.numError += 1 return False return True
#--------------------------------------------------------------------
[ドキュメント] def proccessARG(self, tkn): """check ARG 引数について処理を施す """ if self.argOpt[0] == 1: if self.argOpt[1] == 1: #imm19 branch self.linTemp += "s." + tkn[1] + " " elif self.argOpt[1] == 2: #align if tkn[1] == "2": self.linTemp += "1 " elif tkn[1] == "4": self.linTemp += "2 " elif tkn[1] == "8": self.linTemp += "3 " elif tkn[1] == "16": self.linTemp += "4 " elif tkn[1] == "32": self.linTemp += "5 " else: self.linTemp += tkn[1] + " WARNING!-Unknown-alignment " self.numWarning += 1 self.forceComment = True self.release = True elif self.argOpt[1] == 3: #mov_imm16 self.linTemp += "z." + self.convHexFormat(tkn[1]) + " " elif self.argOpt[1] == 4: #org adr = self.convHexFormat(tkn[1], True) if adr == 0x40000000: self.linTemp += "_start:" elif (adr > 0x40000000) and (adr < 0x40010000): self.linTemp += " .org " + hex(adr - 0x40000000) elif adr == 0x60000000: self.linTemp += ".data" elif (adr > 0x60000000) and (adr < 0x60100000): self.linTemp += " .org " + hex(adr - 0x60000000) elif self.detectHardwareLocation(tkn[1]): self.linTemp += " .org SANITIZED: " + tkn[1] self.forceComment = True self.sanitized += 1 else: if self.forceComment: self.linTemp += " .org " + tkn[1] + " " else: self.linTemp += " .org # WARNING!-origin-address-?= " + tkn[1] self.numWarning += 1 self.forceComment = True self.release = True else: self.linTemp += tkn[1] + " " self.argOpt = [0, 0] elif self.argOpt[0] > 1: self.linTemp += tkn[1] + " " self.argOpt[0] -= 1 else: if self.forceComment: #コメントにする場合は何もせずに流す self.linTemp += tkn[1] + " " elif self.INCL: #incl疑似命令の処理 if tkn[0]==99 : self.linTemp += ".include \"" + tkn[1] + ".s\"" else: self.linTemp += "#.list WARNING!-unexpected-incl-argument-?=" + tkn[1] self.numWarning += 1 elif self.listArgP: #list疑似命令の処理 if tkn[0]==99 and tkn[1]=="on": self.linTemp += ".list" elif tkn[0]==99 and tkn[1]=="off": self.linTemp += ".nolist" else: self.linTemp += "#.list WARNING!-unknown-list-argument-?=" + tkn[1] self.numWarning += 1 elif self.fifoFlag: #FIFO系命令の引数の処理 num = tryIntParse(tkn[1], 16) if num < 16: self.linTemp += tkn[1] elif tkn[1] in self.equDic: self.linTemp += str(self.equDic[tkn[1]]) else: self.forceComment = True self.release = True self.linTemp += "# WARNING!-unexpected-fifo-argument-?=" + tkn[1] self.numWarning += 1 elif tkn[0] == 2: # { self.linTemp += "( " elif tkn[0] == 3: # } self.linTemp += ") " elif tkn[0] == 19: #location counter self.linTemp += " WARNING!-location-counter-found $ " self.numWarning += 1 self.forceComment = True self.release = True elif self.macroPending: #マクロ引数チェック、マクロに引数あり if tkn[0] == 20: # , self.linTemp += ", " else: self.linTemp += tkn[1] + " " self.convMacroArgs = True self.macroArgs.append(tkn[1]) elif self.convMacroArgs: #引数ありマクロの展開中 zFlag = False tmpArg = tkn[1] if (len(tmpArg) > 2) and (tmpArg[0:2] == "z."): tmpArg = tmpArg[2:len(tmpArg)] zFlag = True if tmpArg in self.macroArgs: if zFlag: self.linTemp += "z.\\" + tmpArg + " " else: self.linTemp += "\\" + tmpArg + " " else: self.linTemp += self.convHexFormat(tkn[1]) + " " else: self.linTemp += self.convHexFormat(tkn[1]) + " " if self.equFlag: #EQU が99以下の単純な数値なら覚える num = tryIntParse(tkn[1], 100, 10) if num < 100: self.equDic[self.equKEY]=num self.equFlag = False return
#--------------------------------------------------------------------
[ドキュメント] def detectHardwareLocation(self, arg): """detect Hardware Location 事前定義されているハードウエアロケーションか否かを判定する """ if arg.endswith("addr_htu_top"): return True elif arg=="htu_buffer": return True elif arg.endswith("addr_htu_reg"): return True elif arg.endswith("addr_hru_top"): return True elif arg=="hru_buffer": return True elif arg.endswith("addr_hru_reg"): return True else: return False
#--------------------------------------------------------------------
[ドキュメント] def convHexFormat(self, arg, opt=False): """convert hex Format インテルHEX式の16進数表記であれば、C形式のHEXに置き換える. opt=Trueであれば数値として返す そうでなければ何もしない """ zFlag = False if len(arg) > 2: if arg[len(arg)-1].lower() == "h": tempStr = arg[0:len(arg)-1] if tempStr[0:2] == "z.": tempStr = tempStr[2:len(tempStr)] zFlag = True try: test = int(tempStr, 16) except: if opt: return 0 else: return arg if opt: return test if tempStr[0]=="0": tempStr = tempStr[1:len(tempStr)] #print arg + "=" + tempStr, if zFlag: #print arg + "= z.0x" + tempStr return "z.0x" + tempStr return "0x" + tempStr return arg
#--------------------------------------------------------------------
[ドキュメント] def checkID1(self): """check ID1 最初の識別子を検査し、変換不要な場合はコメント化する 必要な場合は変換する. gasに変換する場合に問題が起こるケースもコメント化する """ #if self.forceComment: #コメントに落とす場合は何もしない # self.linTemp += " " + self.linID1 + " " if self.linID1 == "cpu": self.linTemp += "# SANITIZED: cpu " self.sanitized += 1 elif self.linID1 == "hof": self.linTemp += "# SANITIZED: hof " self.sanitized += 1 elif self.linID1 == "org": self.argOpt = [1, 4] elif (self.linID1 == "dd") or (self.linID1 == "dll"): self.linTemp += " .long " elif (self.linID1 == "dw") or (self.linID1 == "dwl"): self.linTemp += " .short " elif (self.linID1 == "db") or (self.linID1 == "dfb"): self.linTemp += " .byte " elif (self.linID1 == "ds") or (self.linID1 == "dfs"): self.linTemp += " .zero " elif self.linID1 == "align": self.linTemp += " .align " self.argOpt = [1, 2] elif self.linID1 == "br_imm19": self.linTemp += " br.imm19 " self.argOpt = [1, 1] elif self.linID1 == "bt_imm19": self.linTemp += " bt.imm19 " self.argOpt = [1, 1] elif self.linID1 == "bf_imm19": self.linTemp += " bf.imm19 " self.argOpt = [1, 1] elif self.linID1 == "bsr_imm19": self.linTemp += " bsr.imm19 " self.argOpt = [1, 1] elif self.linID1 == "mov_imm16": self.linTemp += " movi.imm16 " self.argOpt = [3, 3] elif self.linID1 == "fpush": self.linTemp += " fpush" self.fifoFlag = True elif self.linID1 == "fpop": self.linTemp += " fpop" self.fifoFlag = True elif self.linID1 == "fisync": self.linTemp += " fisync" self.fifoFlag = True elif self.linID1 == "fosync": self.linTemp += " fosync" self.fifoFlag = True elif self.linID1 == "endm": if self.forceComment: self.linTemp += "#.endm " self.forceComment = False else: self.linTemp += ".endm " self.macroArgs = [] self.convFacroArgs = False elif self.linID1 == "if": self.linTemp += ".if " if not self.forceComment: self.ifNest += 1 elif self.linID1 == "else": self.linTemp += ".else " elif self.linID1 == "endi": self.linTemp += ".endif " if not self.forceComment: self.ifNest -= 1 elif self.linID1 == "list": self.listArgP = True elif self.linID1 == "incl": self.INCL = True else: self.linTemp += " " + self.linID1 + " " return
#--------------------------------------------------------------------
[ドキュメント] def checkAlias(self, lbl): """check Alias 既知のAliasであればSanitized分類に落とす 既知でなければWarning分類に落とす いずれもコメント化する """ if (lbl == "db") or (lbl == "dw") or (lbl == "dd") or (lbl == "ds"): self.linTemp += "# SANITIZED: " + self.linLabel + " " + self.linID1 + " " self.sanitized += 1 else: self.linTemp += "# WARNING! " + self.linLabel + " " + self.linID1 + " " self.numWarning += 1
#--------------------------------------------------------------------
[ドキュメント] def checkMacro(self, lbl): """check Macro 既知で代替命令の存在するMacroであればSanitized分類に落とす 既知でなければ Macro変換保留扱いとしてマクロ引数へ進む """ if (lbl == "push") or (lbl == "pop") or (lbl == "mov_imm16") or (lbl == "align") or \ (lbl == "br_imm19") or (lbl == "bsr_imm19") or (lbl == "bt_imm19") or (lbl == "bf_imm19") or \ (lbl == "blkcopy") or (lbl == "strcomp") or (lbl == "movl"): self.linTemp += " SANITIZED: " + self.linLabel + " " + self.linID1 + " " self.forceComment = True self.sanitized += 1 else: self.linTemp += ".macro " + self.linLabel + " " self.macroPending = True
#--------------------------------------------------------------------
[ドキュメント] def checkEqu(self, lbl): """check Equ 既知のEquであればSanitized分類に落としてコメント化する 既知でなければ.equ命令に形式変換する """ if (lbl.startswith("sizeof_user_stack") or lbl.startswith("sizeof_system_stack")): self.linTemp += " SANITIZED: .equ " + self.linLabel + ", " self.forceComment = True self.release = True self.sanitized += 1 else: self.linTemp += " .equ " + self.linLabel + ", " self.equFlag = True self.equKEY = self.linLabel
#--------------------------------------------------------------------
[ドキュメント] def checkLabelID1(self): """check Label + ID1 Label + ID1形式の特定の組み合わせをコメント化する 必要な場合は変換する. gasに変換する場合に問題が起こるケースもコメント化する """ if self.linID1 == "alias": self.checkAlias(self.linLabel) elif self.linID1 == "equ": self.checkEqu(self.linLabel) elif self.linID1 == "setl": self.linTemp += " .set " + self.linLabel + ", " elif self.linID1 == "macro": self.checkMacro(self.linLabel) else: elf.linTmep += self.linLabel + " " + self.linID1 + " " return
#--------------------------------------------------------------------
[ドキュメント] def writeRawToken(self, tkn): """write Token(RAW) to buffer 生トークンをバッファへ書き込むためのメソッド. 0, EOL 1, COMMENT 2, { 3, } 4, [ 5, ] 6, + 7, - 8, * 9, / 10, < 11, > 12, << 13, >> 14, <= 15, >= 16, == 17, != 18, : 19, $ 20, , 21, % 22, & 23, | 99, "string" 100, ID 200, LABEL 999, ERROR-Message """ if tkn[0]==0: self.bufList.append("EOL : " + tkn[1]) elif tkn[0]==1: self.bufList.append("COMMENT : " + tkn[1]) elif (tkn[0] > 1) and (tkn[0] < 99): self.bufList.append(tkn[1] + " : " + tkn[1]) elif tkn[0] ==99: self.bufList.append("STRING : " + tkn[1]) elif tkn[0] ==100: self.bufList.append("ID : " + tkn[1]) elif tkn[0] ==200: self.bufList.append("LABEL : " + tkn[1]) else: self.bufList.append("999 : " + tkn[1]) return False return True
#--------------------------------------------------------------------
[ドキュメント] def writePredef(self): """write Predefined macros/definitions """ today = datetime.today() self.bufList.append("# file converted by " +versionSTR ); self.bufList.append("# " + today.strftime("%Y/%m/%d %H:%M:%S")) if self.inc: self.bufList.append("# INC FILE conversion mode.") else: self.bufList.append(".altmacro") self.bufList.append("") self.bufList.append(".macro push regname") self.bufList.append(" subi r14, z.4") self.bufList.append(" st [r14+z.0], \\regname") self.bufList.append(".endm") self.bufList.append("") self.bufList.append(".macro pop regname") self.bufList.append(" ld \\regname, [r14+z.0]") self.bufList.append(" addi r14, z.4") self.bufList.append(".endm") self.bufList.append("") self.bufList.append(".macro movl reg, val") self.bufList.append(".balignw 4, 0xE000") self.bufList.append(".hword 0xB012") self.bufList.append(".hword 0x1002") self.bufList.append(".long \\val") self.bufList.append(".endm") self.bufList.append("") self.bufList.append(" .equ htu_buffer, __addr_htu_top") self.bufList.append(" .equ hru_buffer, __addr_hru_top") self.bufList.append("") self.bufList.append(".text") self.bufList.append("") self.bufList.append(".globl _start") self.bufList.append("")
#======================================================================= # メインプログラム def main(): """main. メインプログラム """ #----------------------------------------------------------------------- # コマンドラインオプション処理 # parser = argparse.ArgumentParser(description='asm2s.') parser.add_argument('--ASM', nargs=1, help='Specify ASM file name.') parser.add_argument('--S', nargs=1, help='Specify S file name.') parser.add_argument('-i', dest='inc', help='INC file mode.', action='store_true', default=False) parser.add_argument('-d', dest='debug', help='Debug mode, print debug information.', action='store_true', default=False) parser.add_argument('-v', dest='verbose', help='Verbose mode.', action='store_true', default=False) parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False) args = parser.parse_args() #----------------------------------------------------------------------- # Version 表示 # print versionSTR if args.VERSION: sys.exit(0) #----------------------------------------------------------------------- # ファイル名処理 # if args.ASM is None: errPrint('ERROR: NO input ASM file!!!') sys.exit(1) else: asmFname = args.ASM[0] if not os.path.isfile(asmFname): errPrint('ERROR: ASM file, NOT EXIST.') sys.exit(1) if args.S is None: sFname = "asm_converted.s" else: sFname = args.S[0] #----------------------------------------------------------------------- # パラメータ処理 #----------------------------------------------------------------------- # 実処理 # writer = gasWriter(sFname, args.inc) writer.verbose = args.verbose writer.debug = args.debug # convertor = asmReader(asmFname, writer, None) convertor.verbose = args.verbose convertor.debug = args.debug if convertor.read(): if not writer.save(): sys.exit(1) else: sys.exit(1) print "# of ERROR: " + str(writer.numError) print "# of WARNING: " + str(writer.numWarning) print "# of SANITIZED: " + str(writer.sanitized) #終了メッセージ today = datetime.today() print " " print today.strftime("FINISH: %Y/%m/%d %H:%M:%S") #----------------------------------------------------------------------- # 正常終了 # sys.exit(0) #======================================================================= # メインプログラムの起動 if __name__ == "__main__": main()