import ply.lex as lex keywords = ( 'int','String' ) tokens = ( 'NAME','NUMBER','INT','STRING','STRING_LIT','COMMENT','NEWLINE' ) literals = ['=','+','-','*','/', '(',')','{','}','[',']',';','%'] # Tokens t_ignore = " \t" t_STRING = r'"[a-zA-Z0-9_]*"' t_COMMENT = r'//' def t_NAME(t): r'[a-zA-Z_][a-zA-Z0-9_]*' if t.value in keywords: t.type = t.value.upper() return t def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueError: print ("Integer value too large", t.value) t.value = 0 return t def t_NEWLINE(t): r'\n+' t.lexer.lineno += t.value.count("\n") t.value='\n' return t def t_NEWLINEr(t): r'\r+' t.lexer.lineno += t.value.count("\r") t.type="NEWLINE" t.value='\r' return t def t_error(t): print( "Illegal character '%s'" % t.value[0]) # Build the lexer lex.lex() #lex.input("int skai;\nint lol=skai\ngetKey();") lex.input(open(input("FILE >> ")).read()) out="" data="" lastToken="" nextSlot=500 #500 bytes after program (change if needed) names = {} def getToken(): global lastToken, lex lastToken=lex.token() return lastToken inComment=False jmploc=[] while(lastToken!=None): token=getToken() if(token==None): break; if(token.value=='\n' or token.value=='\r'): inComment=False continue; if(token.value=="//"): inComment=True if(inComment): continue; if(token.type=='INT'): names[getToken().value]=nextSlot nextSlot+=1 name=lastToken.value t=getToken() if(t.value!=';'): t=getToken() if(t.type=="NUMBER"): out+=chr(6)+chr(0)+chr(t.value) elif(t.type=="NAME" and t.value in names): out+=chr(14)+chr(names[t.value]&255)+chr(names[t.value]>>8) # LD SI, input out+=chr(15)+chr(names[name]&255)+chr(names[name]>>8) # LD DI, output out+=chr(0x2B)+chr(0x2A) # LOD / STO getToken() if(lastToken==None or lastToken.value!=';'): print("missing semicolon maybe? line: "+str(lastToken.lineno)) elif(token.value=="getKey"): if(getToken().value=='('): if(getToken()!=None and lastToken.value==')'): print("getKey returns to nothing! line: "+str(lastToken.lineno)) elif(lastToken!=None): out+=chr(0xF0) # KBD AL out+=chr(0x70)+chr(names[lastToken.value]&255)+chr(names[lastToken.value]>>8) # LD [output], AL getToken() else: print("error: EOF while parsing.") break; else: print("getKey is no literal! Missing parenthesis? line: "+str(lastToken.lineno)) getToken() if(lastToken==None or lastToken.value!=';'): print("missing semicolon maybe? line: "+str(lastToken.lineno)) elif(token.value=="outS"): if(getToken().value=='('): if(getToken()!=None and lastToken.value==')'): print("outS has no input! line: "+str(lastToken.lineno)) elif(lastToken!=None): out+=chr(0x90)+chr(names[lastToken.value]&255)+chr(names[lastToken.value]>>8) # LD AL, [input] out+=chr(0x80) # WRT AL getToken() else: print("error: EOF while parsing.") break; else: print("outS is no literal! Missing parenthesis? line: "+str(lastToken.lineno)) getToken() if(lastToken==None or lastToken.value!=';'): print("missing semicolon maybe? line: "+str(lastToken.lineno)) elif(token.value=='%'): token=getToken() if(token.value.upper()=="MEMSTART"): token=getToken() if(token.type!="NUMBER"): print("Invalid value for definition 'MEMSTART' at line "+str(token.lineno)) continue; nextSlot=token.value else: print("invalid '%' 'definition'. line: "+str(token.lineno)) elif(token.value=="while"): if(getToken().value=='('): if(getToken()!=None and lastToken.value==')'): print("while statement has no condition! line: "+str(lastToken.lineno)) elif(lastToken!=None): name=lastToken.value getToken() if(getToken().value=='{'): tmp=chr(0x90)+chr(names[name]&255)+chr(names[name]>>8) # LD AL, [input] tmp+=chr(0xD0)+chr(len(out)-1&255)+chr(len(out)-2>>8) # JPZ start_of_while_loop out+=chr(0x90)+chr(names[name]&255)+chr(names[name]>>8) # LD AL, [input] out+=chr(0x4A)+chr(0)+chr(1) # CP AL, 1 out+=chr(0xD0)+chr(len(out)-1&255)+chr(len(out)-2>>8) # JP end_of_while_loop jmploc.append([tmp,len(out)-2]) elif(lastToken.value==';'): out+=chr(0xC3)+chr(len(out)-1&255)+chr(len(out)-2>>8) # JMP $ else: print("error: EOF while parsing.") break; else: print("while is no literal! Missing parenthesis? line: "+str(lastToken.lineno)) elif(token.value=='}'): t=jmploc.pop() out+=t[0] out = out[:t[1]] + chr(len(out)>>8) + out[t[1]+1:] out = out[:t[1]+1] + chr(len(out)&255) + out[t[1]+2:] else: print("strange token '"+token.value+"' , line "+str(token.lineno))