"""One Flat (Ib) compiler by nm 2005-11-13, MIT License, see oneflat.txt

Usage:  oneflat source.one [-o executable]
        oneflat -v"""

__version__ = "1.0"

import getopt, os, struct, sys

# Check arguments
outFileName = 'a.out'
try:
    opts, args = getopt.gnu_getopt(sys.argv[1:], 'ho:uv', ['help', \
        'output=', 'version', 'usage'])
except getopt.GetoptError:
    sys.exit(__doc__)
if len(args) < 1:
      sys.exit(__doc__)
for o, a in opts:
   if o in ('-h', '-u', '--help', '--usage'):
      sys.exit(__doc__)
   if o in ('-v', '--version'):
      sys.exit('One Flat version ' + __version__)
   if o in ('-o', '--output'):
      outFileName = a
inFileName = args[0]

codeNumber = 0;
try:
    sourceFile = open(inFileName, 'rb')
except:
    sys.exit('FATAL ERROR: Cannot open ' + inFileName + ' for reading.')
sourceToken = sourceFile.read(1)
while len(sourceToken) > 0:
    if (sourceToken == '\n'):
        if sourceFile.read(1):
            sys.exit('FATAL ERROR: Source file continues after newline.')
        else:
            break
    if sourceToken=='1':
        print 'WARNING in line 1: \"1\" is deprecated. Use \"I\" instead.'
        sourceToken = "I"
    if sourceToken!='I':
        sys.exit('FATAL ERROR in line 1: Found << ' + \
            sourceToken + ' >>, which is not \"I\" or \"1\".')
    else:
        codeNumber += 1;
        sourceToken = sourceFile.read(1)

print 'Code number:', codeNumber
objectCode = hex(codeNumber)[2:]
try:
    binaryFile = open(outFileName, 'wb')
except:
    sys.exit('FATAL ERROR: Cannot open ' + outFileName + ' for writing.')
if len(objectCode) % 2:
    objectCode = '0' + objectCode
for i in range(0, len(objectCode)-1, 2):
    a = (int(objectCode[i], 16) * 16) + int(objectCode[i+1], 16)
    binaryFile.write(struct.pack('B',a))
    print 'Writing', hex(a), '...'
binaryFile.close
os.chmod(outFileName,0755)
print 'Finished.'
