I am making a language in python called PythonScript, which is a JavaScript and Python (not Python 3) mix.
I am adding variables, but when I do the following code I don't get the expected result.
var scuffles = hi!
I have tried to debug it, and as you will see in my code I made a debugging array, which I found to be empty. I looked up some tutorials, but none were covering what I am trying to do.
This is a portion of the file:
import os
import sys
programDebugingArray1 = []
functions = ["Console"]
functionCodes = [["out \"TEST\""]]
programVariables = {}
def lex(cm,stri,nums,toWake):
i = 0
if cm == "":
console()
elif cm == "var" or cm == "=":
pass
elif cm == "--vars":
print(programVariables)
elif cm == "--debugManual1":
print(programDebugingArray1)
else:
print("\""+cm+"\" was not recognized as a PythonScript command.")
console()
def console():
commandToRun = ""
tok = ""
string = ""
varValue = ""
newVarName = ""
Strings = []
Numbers = []
functionToCall = ""
state = 0
command = input()
for char in command:
tok += char
if state == 1:
string += char
elif state == 2:
if char == " ":
char = ""
newVarName += char
elif state == 3:
varValue += char
if (tok == "\"" or tok == "'") or (char == "\"" or char == "'"):
if state == 0:
state = 1
elif state == 1:
state = 0
string = string[0:len(string) - 1]
Strings.append(string)
string = ""
tok = ""
char = ""
elif tok == " ":
tok = ""
elif tok == "var" and state == 0:
state = 2
tok = ""
elif tok == "=" and state == 2:
state = 3
tok = ""
elif tok == "!" and state == 3:
programDebugingArray1.append(newVarName)
programDebugingArray1.append(varValue)
state == 0
programVariables[newVarName] = varValue
tok = ""
elif tok == "--vars" and state == 0:
commandToRun == "--vars"
tok = ""
elif tok == "--debugManual1" and state == 0:
commandToRun == "--debugManual1"
tok = ""
if commandToRun == "":
commandToRun = command
lex(commandToRun,Strings,Numbers,functionToCall)
console()
I expected the debug array to at least have something in it, but for some reason it and the variables dictionary is empty. There are no error messages or boots out of the console.
Related
i understand that this error happens when a variable gets mentioned before its defined but "key" is assigned to its value. I started learning python a week ago so i am sorry if my question has a really simple answer.
the code:
from stat import SF_APPEND
import time
import random
keyType = 0
key = 0
deCypherKey = 0
operationType = 0
needToLoop = True
alphabet = "abcdefghijklmnopqrstuvwxyz "
print("ogulSifreleyici v1.0")
time.sleep(0.3)
print("Ipucu: Hem Sifrelemek Hem de Desifrelemek Icin Programi 2 Kere Calistirabilirsiniz")
def cypher():
message = input("Mesajini Gir:\n")
message = message.lower()
unCypheredMessageLength = len(message)
letterOfMessageInQueue = 0
keyStr = str(key)
keyStrInt = 0
whichOrderOfAlphabet = 0
whichLetterOfAlphabet = " "
whichDigitOfKey = 0
orderOfCypheredLetter = 0
cypheredLetter = "a"
cypheredMessageList = []
cypheredStr = ""
while unCypheredMessageLength > 0:
whichLetterOfAlphabet = alphabet[whichOrderOfAlphabet]
if message[letterOfMessageInQueue] == whichLetterOfAlphabet:
print("match")
print(whichOrderOfAlphabet, message[letterOfMessageInQueue], whichLetterOfAlphabet)
keyStrInt = int(keyStr[whichDigitOfKey])
orderOfCypheredLetter = whichOrderOfAlphabet + keyStrInt
if orderOfCypheredLetter > 26:
orderOfCypheredLetter = orderOfCypheredLetter - 26
cypheredLetter = alphabet[orderOfCypheredLetter]
cypheredMessageList.append(cypheredLetter)
unCypheredMessageLength = unCypheredMessageLength - 1
letterOfMessageInQueue = letterOfMessageInQueue + 1
whichOrderOfAlphabet = 0
whichDigitOfKey = whichDigitOfKey + 1
if whichDigitOfKey > 4:
whichDigitOfKey = whichDigitOfKey - 5
if len(cypheredMessageList) == len(message):
cypheredStr = "".join(cypheredMessageList)
print("Sifrelenmis Mesajiniz:\n" + cypheredStr)
time.sleep(1)
lastUserAnswer = input("1-Sifrele(Ayni Anahtar) 2-Sifrele(Farkli Anahtar)\n")
if lastUserAnswer == "1":
cypher()
if lastUserAnswer == "2":
key = input("Anahtar Giriniz(5 Haneli Sayi):\n")
while len(str(key)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
cypher()
cypher()
else:
whichOrderOfAlphabet = whichOrderOfAlphabet + 1
def deCypher():
deCypherMessage = input("Sifreli Mesajinizi Giriniz:\n")
operationType = input("1-Sifrele 2-DeSifrele\n")
while needToLoop == True:
if operationType == "1":
keyType = input("1-Anahtar gir(5 haneli sayi) 2-Rastgele Anahtar\n")
if keyType == "1":
key = input("Anahtar Giriniz:\n")
while len(str(key)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
needToLoop = False
cypher()
needToLoop = False
cypher()
if keyType == "2":
key = int(random.uniform(10000, 100000))
print("Anahtariniz: " + str(key))
cypher()
needToLoop = False
else:
print("Lutfen Seceneklerden Birini Seciniz")
needToLoop = True
if operationType == "2":
deCypherKey = input("Anahtarinizi Giriniz:\n")
while len(str(deCypherKey)) != 5:
key = input("Lutfen Bes Haneli Bir Sayi Giriniz\n")
if len(str(key)) == 5:
needToLoop = False
deCypher()
needToLoop = False
deCypher()
else:
print("Lutfen Seceneklerden Birini Seciniz")
needToLoop = True
this is not exactly the reason you wrote, the fact is that the function cannot see variables that are outside the function. In order for the function to see them, you need to pass the variable as an argument to the function. That is, you need to change line 86 like this: cypher(key). But as you can see, this will give an error, because your function initially does not accept any arguments, in order to fix this we need to add the key argument in line 16 like this: def cypher(key):. There is the site where you can read more about it https://levelup.gitconnected.com/5-types-of-arguments-in-python-function-definition-e0e2a2cafd29
I don't know what to add. At the time that's why I only posted the code.
But the intended result is that a string should be parsed (and successfully printed).
I don't remember what the issue was, but by the sounds of it, it probably just didn't print.
(I'm doing this to get back on S.O.'s "good side".)
class Lex:
def run(args, string):
if args == "print":
print(str(string))
class Calin:
string = ""
running = ""
def parse(args):
lexic = Lex
string = ""
tok = ""
state = 0
for char in args:
tok += char
if tok == " ":
if state == 0:
tok = ""
elif state == 1:
tok = " "
elif tok == "\"":
if state == 0:
state = 1
elif state == 1:
state = 0
elif state == 1:
string += char
elif tok == "print":
running = "print"
lexic.run(running, string)
trans = Calin
trans.parse("print \"WOW A STRING\"")
Because you are making state == 1 only when tok == "\"", which never happens (You are keep adding strs to it.). Changing it to char works:
class Lex:
def run(args, string):
if args == "print":
print(str(string))
class Calin:
string = ""
running = ""
def parse(args):
lexic = Lex
string = ""
tok = ""
state = 0
for char in args:
tok += char
if tok == " ":
if state == 0:
tok = ""
elif state == 1:
tok = " "
elif char == "\"": # <<< Change this
if state == 0:
state = 1
elif state == 1:
state = 0
elif state == 1:
string += char
elif tok == "print":
running = "print"
lexic.run(running, string)
trans = Calin
trans.parse("print \"WOW A STRING\"")
# WOW A STRING
I am trying to make my own basic programming language. I have the following code in my smrlang.py file
from sys import *
tokens = []
def open_file(filename):
data = open(filename, "r").read()
return data
def smr(filecontents):
tok = ""
state = 0
string = ""
filecontents = list(filecontents)
for char in filecontents:
tok += char
if tok == " ":
if state == 0:
tok = ""
else:
tok = " "
elif tok == "PRINT":
tokens.append("PRINT")
tok = ""
elif tok == "\"":
if state == 0:
state = 1
elif state == 1:
print("STRING")
string = ""
state = 0
elif state == 1:
string += tok
print(tokens)
def run():
data = open_file(argv[1])
smr(data)
run()
And I have this in my one.smr file:
PRINT "HELLO WORLD"
The output should be something like PRINT STRING, but when I use the command python3 smrlang.py one.smr, the output is just PRINT. I am using Python 3
Debugging it in the head, I found the problem:
elif state == 1:
string += tok
You don't reset the token here. It will be aababcabcd instead of abcd and recognizing \ won't work (as it will be aababcabcd\).
This also causes the token to just be everything and it will never print.
Try changing it to:
elif state == 1:
string += tok
tok = ""
Output after fix:
> py -3 temp.py temp.txt
STRING
['PRINT']
For some reason I get an error in python 2.7 when running this and entering in my 26 letter key. It says that the list index is out of range. Any help would be greatly appreciated. Thanks! (And I know I could've used a loop for the encrypter)
#-------------------------#
# Code Translator #
#-------------------------#
message = ''
messagearray = []
user = ''
encrypted = []
decrypted = []
keystring = ''
alphabet = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
dataset = []
keyarray = []
def encrypter():
keystring = raw_input("Please paste key: ")
message = raw_input("Message to Encrypt: ")
for char in message:
if char == alphabet[0]:
messagearray.append(keyarray[0])
elif char == alphabet[1]:
messagearray.append(keyarray[1])
elif char == alphabet[2]:
messagearray.append(keyarray[2])
elif char == alphabet[3]:
messagearray.append(keyarray[3])
elif char == alphabet[4]:
messagearray.append(keyarray[4])
elif char == alphabet[5]:
messagearray.append(keyarray[5])
elif char == alphabet[6]:
messagearray.append(keyarray[6])
elif char == alphabet[7]:
messagearray.append(keyarray[7])
elif char == alphabet[8]:
messagearray.append(keyarray[8])
elif char == alphabet[9]:
messagearray.append(keyarray[9])
elif char == alphabet[10]:
messagearray.append(keyarray[10])
elif char == alphabet[11]:
messagearray.append(keyarray[11])
elif char == alphabet[12]:
messagearray.append(keyarray[12])
elif char == alphabet[13]:
messagearray.append(keyarray[13])
elif char == alphabet[14]:
messagearray.append(keyarray[14])
elif char == alphabet[15]:
messagearray.append(keyarray[15])
elif char == alphabet[16]:
messagearray.append(keyarray[16])
elif char == alphabet[17]:
messagearray.append(keyarray[17])
elif char == alphabet[18]:
messagearray.append(keyarray[18])
elif char == alphabet[19]:
messagearray.append(keyarray[19])
elif char == alphabet[20]:
messagearray.append(keyarray[20])
elif char == alphabet[21]:
messagearray.append(keyarray[21])
elif char == alphabet[22]:
messagearray.append(keyarray[22])
elif char == alphabet[23]:
messagearray.append(keyarray[23])
elif char == alphabet[24]:
messagearray.append(keyarray[24])
elif char == alphabet[25]:
messagearray.append(keyarray[25])
print ''.join(messagearray)
def decrypter():
keystring = raw_input("Please paste key: ")
message = raw_input("Message to Decrypt: ")
def outputM():
print decrypted
def userChoice():
user = raw_input("Encrypt or Decrypt?")
if user.upper() == "ENCRYPT":
encrypter()
elif user.upper() == "DECRYPT":
decrypter()
else:
print "Please enter a valid command."
userChoice()
for char in keystring:
keyarray.append(char)
userChoice()
Here's the full traceback I get:
Traceback (most recent call last):
File "translate.py", line 102, in <module>
userChoice()
File "translate.py", line 92, in userChoice
encrypter()
File "translate.py", line 43, in encrypter
messagearray.append(keyarray[11])
IndexError: list index out of range
The problem is here:
for char in keystring:
keyarray.append(char)
keystring is empty so also keyarray will remain empty. In order not to have IndexError you would need a keystring as much longer as the alphabet (since basically you are just substituting chars)
The problem is that in:
def decrypter():
keystring = raw_input("Please paste key: ")
message = raw_input("Message to Decrypt: ")
you are assigning the values to local variables, so the global ones remain empty. If you want to modify the global variables you have to state so:
def decrypter():
global keystring, message
keystring = raw_input("Please paste key: ")
message = raw_input("Message to Decrypt: ")
the same is true for encrypter.
Also, you cannot create keyarray before having taken some input!
There are also many other issues with the code. You cannot possibly think that doing all the manual indexing is the best way to proceed. What if you want to support a 128 character alphabet?
Use loops:
for char in message:
for i, c in enumerate(alphabet):
if char == c:
messagearray.append(keyarray[i])
(Instead of all those repeating lines).
Moreover strings already provide a method to do exactly what you are trying to do. It's called translate.
You could simply do:
import string
table = str.maketrans(string.ascii_lowercase, keystring)
And then use:
decrypted_text = some_encrypted_text.translate(table)
example run:
In [1]: import string
...: alphabet = string.ascii_lowercase
...: table = str.maketrans(alphabet, alphabet[3:]+alphabet[:3])
...:
In [2]: 'hello'.translate(table)
Out[2]: 'khoor'
The above is for python3+. In python2.7 you have to use string.maketrans instead of str.maketrans. So you'd have to do:
In [1]: import string
...: alphabet = string.ascii_lowercase
...: table = string.maketrans(alphabet, alphabet[3:]+alphabet[:3])
...:
In [2]: 'hello'.translate(table)
Out[2]: 'khoor'
This is the basic.py file for a programming language I am making. At the moment it is throwing an error.
from sys import *
tokens = []
def open_file(filename):
data = open(filename, "r").read()
data += "<EOF>"
return data
def lex(filecontents):
tok = ""
state = 0
isexpr = 0
string = ""
expr = ""
n = ""
filecontents = list(filecontents)
for char in filecontents:
tok += char
if tok == " ":
if state == 0:
tok = ""
else:
tok = " "
elif tok == "\n" or tok == "<EOF>":
if expr != "" and isexpr == 1:
#print(expr + "EXPR")
tokens.append("EXPR:" + expr)
expr = ""
elif expr != "" and isexpr == 0:
#print(expr + "NUM")
tokens.append("NUM:" + expr)
expr = ""
tok = ""
elif tok.lower() == "print":
tokens.append("PRINT")
tok = ""
elif tok.isnumeric():
expr += tok
tok = ""
elif tok == "+":
isexpr = 1
expr += tok
tok = ""
elif tok == "\"":
if state == 0:
state = 1
elif state == 1:
tokens.append("STRING:" + string + "\"")
string = ""
state = 0
tok = ""
elif state == 1:
string += tok
tok = ""
print(tokens)
return tokens
def parse(toks):
i = 0
while(i < len(toks)):
if toks[i] + " " + toks[i+1][0:6] == "PRINT STRING" or toks[i] + " " + toks[i+1][0:3] == "PRINT NUM" or toks[i] + " " + toks[i+1][0:4] == "PRINT EXPR":
if toks[i+1][0:6] == "STRING":
print(toks[i+1][7:])
elif toks[i+1][0:3] == "NUM":
print(toks[i+1][4:])
elif toks[i+1][0:4] == "EXPR":
print(toks[i+1][5:])
i+=2
def run():
data = open_file(argv[1])
toks = lex(data)
parse(toks)
run()
here is the test.vil file(my programming language is called villar) that I am passing data through:
STRING "HELLO WORLD"
string "Hey world!"
17 + 3
As a result, I get an IndexError: List index out of range in line 62.
Can you anyone help me help here? I'd love advice on how to improve it to if its allowed here.
You've got the line:
while(i < len(toks)):
in the parse function. However, within this while loop, you access toks[i+1] element, which'll be out of bounds on the final iteration of the while loop (as i == len(toks)-1 and i+1 == len(toks) which is out of bounds and throwing an error). You need to change that above line to:
while(i < len(toks)-1):
so that on the final iteration i == len(toks) - 2 and i+1 == len(toks) - 1 which are both in bounds.