Advertisement
3snoW

Drive-In Window Interpreter

Mar 5th, 2019
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.29 KB | None | 0 0
  1. # Hi, welcome to Drive-In Window Interpreter. Here is the menu.
  2. #
  3. # to know more about this programming language: $0
  4. #
  5. # Here are your sides.
  6. #
  7. # Interpreter Author 3snoW:  $2019
  8. # Language Creator JWinslow23: $2013
  9. # Marshmallows: $5
  10. #
  11. # May I take your order?
  12. #
  13. # Person 1 would like to know more about this programming language.
  14. #
  15. # OK, that will be https://esolangs.org/wiki/Drive-In_Window. Thanks for coming!
  16.  
  17. import sys
  18.  
  19. showWarnings = False #Change to true to display warning messages!
  20.  
  21. def _find_getch():
  22.     try:
  23.         import termios
  24.     except ImportError:
  25.         # Non-POSIX. Return msvcrt's (Windows') getch.
  26.         import msvcrt
  27.         return msvcrt.getch
  28.  
  29.     # POSIX system. Create and return a getch that manipulates the tty.
  30.     import sys, tty
  31.     def _getch():
  32.         fd = sys.stdin.fileno()
  33.         old_settings = termios.tcgetattr(fd)
  34.         try:
  35.             tty.setraw(fd)
  36.             ch = sys.stdin.read(1)
  37.         finally:
  38.             termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
  39.         return ch
  40.  
  41.     return _getch
  42.  
  43. getch = _find_getch()
  44.  
  45. def printErrorMessage(filename,line_number,line,message):
  46.     errorMessage = "\n"+'Error while parsing \''+filename+'\' at line '+str(line_number) + ' : ' + line
  47.     errorMessage += "\n\t" + message
  48.     print errorMessage
  49.  
  50. def printWarningMessage(filename,line_number,line,message):
  51.     errorMessage = 'Warning while parsing \''+filename+'\' at line '+str(line_number) + ' : ' + line
  52.     errorMessage += "\n\t" + message
  53.     print errorMessage
  54.  
  55. if(len(sys.argv) > 1):
  56.     filename = sys.argv[1]
  57. else:
  58.     print 'File to parse: '
  59.     filename = raw_input().strip()
  60.  
  61. commands = []
  62. f = open(filename,'r')
  63. for line in f:
  64.     commands.append(line.strip())
  65. f.close()
  66.  
  67. people = {}
  68. menu = {}
  69. for_dict = {}
  70. end_for_dict = {}
  71.  
  72. declarationState = 'start'
  73. errorMessage = ''
  74. line_number = 0
  75. success = True
  76. digits = '0123456789'
  77.  
  78. while line_number < len(commands):
  79.     line = commands[line_number]
  80.     warningMessage = ''
  81.     line = line.strip()
  82.     if not line:
  83.         line_number += 1
  84.         continue
  85.     if declarationState == 'start':
  86.         split_line = line.split('Hi, welcome to ')
  87.         if len(split_line)<2:
  88.             success = False
  89.         else:
  90.             split_line = split_line[1]
  91.             split_line = split_line.split('. Here is a menu.')[0]
  92.             split_line = split_line.strip()
  93.             if not split_line:
  94.                 success = False
  95.         if not success:
  96.             errorMessage = 'Invalid Restaurant declaration. First sentence must be in the form of "Hi, welcome to __RESTAURANT_NAME__. Here is a menu."'
  97.         else:
  98.             declarationState = 'menu'  
  99.     elif declarationState == 'menu':
  100.         split_line = line.split(':')
  101.         if not len(split_line) == 2:
  102.             if line == 'Here are your sides.' or line == 'May I take your order?':
  103.                 if not menu:
  104.                     success = False
  105.                     errorMessage = 'Menu can\'t be empty!'
  106.                 elif line == 'Here are your sides.':
  107.                     declarationState = 'sides'
  108.                 else:
  109.                     declarationState = 'main'
  110.             else:
  111.                 success = False
  112.                 errorMessage = 'Menu entries must be in the form of "__MENU_ENTRY__: $__PRICE__".'
  113.         else:
  114.             menu_entry = split_line[0].strip()
  115.             price = split_line[1].strip()
  116.             if not price[0] == '$':
  117.                 success = False
  118.                 errorMessage = 'Menu prices must be in dollars.'
  119.             elif not price[-1] == '0':
  120.                 success = False
  121.                 errorMessage = 'Menu prices must be multiples of 10 dollars.'
  122.             else:
  123.                 price = price[1:]
  124.                 for digit in price:
  125.                     if not digit in digits:
  126.                         success = False
  127.                         errorMessage = 'Menu prices must be whole numbers.'
  128.                         break
  129.             if success:
  130.                 if menu_entry in menu:
  131.                     warningMessage = 'Menu entry "'+menu_entry+'" was already declared with a value of $'+str(menu[menu_entry])
  132.                 menu[menu_entry] = int(price)
  133.     elif declarationState == 'sides':
  134.         split_line = line.split(':')
  135.         if not len(split_line) == 2:
  136.             if line == 'May I take your order?':
  137.                 declarationState = 'main'
  138.             else:
  139.                 success = False
  140.                 errorMessage = 'Menu entries must be in the form of "__MENU_ENTRY__: $__PRICE__".'
  141.         else:
  142.             menu_entry = split_line[0].strip()
  143.             price = split_line[1].strip()
  144.             if not price[0] == '$':
  145.                 success = False
  146.                 errorMessage = 'Menu prices must be in dollars.'
  147.             else:
  148.                 price = price[1:]
  149.                 for digit in price:
  150.                     if not digit in digits:
  151.                         success = False
  152.                         errorMessage = 'Menu prices must be whole numbers.'
  153.                         break
  154.             if success:
  155.                 if menu_entry in menu:
  156.                     warningMessage = 'Menu entry "'+menu_entry+'" was already declared with a value of $'+str(menu[menu_entry]+'. Old value was replaced.')
  157.                 menu[menu_entry] = int(price)
  158.     elif declarationState == 'main':
  159.        
  160.         #Person N would (not|also) like what Person Y has.
  161.         if ' would ' in line and ' like what Person ' in line:
  162.             split_line = line.split('Person ')
  163.             if split_line[0] or (not line[-5:] == ' has.') or (not len(split_line)==3):
  164.                 success = False
  165.                 errorMessage = 'Invalid syntax.'
  166.             else:
  167.                 person1 = split_line[1].split(' would ')[0].strip()
  168.                 person2 = split_line[2].split(' has.')[0].strip()
  169.                 modifier = split_line[1].split(' would ')[1].split(' like ')[0].strip()
  170.  
  171.                 for digit in person1:
  172.                     if not digit in digits:
  173.                         success = False
  174.                         errorMessage = 'Person must be a positive whole number.'
  175.                         break
  176.                 for digit in person2:
  177.                     if not digit in digits:
  178.                         success = False
  179.                         errorMessage = 'Person must be a positive whole number.'
  180.                         break
  181.                 #Parse people:
  182.                 if success:
  183.                     person1 = int(person1)
  184.                     person2 = int(person2)
  185.                     if person1 == 0 or person2==0:
  186.                         success = False
  187.                         errorMessage = 'Person must be greater than 0'
  188.                     elif person1 not in people:
  189.                         people[person1] = 0
  190.                     elif person2 not in people:
  191.                         people[person2] = 0
  192.                 #Assign people:
  193.                 if success:
  194.                     if not modifier:
  195.                         people[person1] = people[person2]
  196.                     elif modifier == 'not':
  197.                         people[person1] -= people[person2]
  198.                     elif modifier == 'also':
  199.                         people[person1] += people[person2]
  200.                     else:
  201.                         success = False
  202.                         errorMessage = '"' + modifier + '" is not a valid modifier for a "would like" command. Valid modifiers are "would not like" and "would also like".'
  203.                     people[person1] %= 256                    
  204.  
  205.         #Person N would (not|also) like menu_item( with side_item|, hold the side_item).
  206.         elif 'Person ' in line and ' would ' in line and ' like ' in line:
  207.             split_line = line.split('Person ')
  208.             if split_line[0] or not line[-1] == '.':
  209.                 success = False
  210.                 errorMessage = 'Invalid syntax.'
  211.             else:
  212.                 split_line = split_line[1].split(' would ')
  213.                 person = split_line[0].strip()
  214.                 split_line = split_line[1].split('like ')
  215.                 item = split_line[1]
  216.                 for digit in person:
  217.                     if not digit in digits:
  218.                         success = False
  219.                         errorMessage = 'Person must be a positive whole number.'
  220.                         break
  221.                 #Parse person
  222.                 if success:
  223.                     person = int(person)
  224.                     if person == 0:
  225.                         success = False
  226.                         errorMessage = 'Person must be greater than 0'
  227.                     elif person not in people:
  228.                         people[person] = 0
  229.                 #Parse menu item and side dish
  230.                 if success:
  231.                     side_price = 0
  232.                     if ' with ' in item or ', hold the ' in item:
  233.                         if ' with ' in item:
  234.                             mod_with = True
  235.                             split_item = item.split(' with ')
  236.                         else:
  237.                             mod_with = False
  238.                             split_item = item.split(', hold the ')
  239.                         item = split_item[0].strip()
  240.                         if item[0:3] == 'the':
  241.                             item = item[3:].lstrip()
  242.                         side = split_item[1]
  243.                         if side[0:3] == 'the':
  244.                             side = side[3:].lstrip()
  245.                         side = side[0:-1].strip()
  246.                         if side not in menu:
  247.                             success = False
  248.                             errorMessage = 'Side dish "'+side+'" was not declared in the menu.'
  249.                         else:
  250.                             if mod_with:
  251.                                 side_price = menu[side]
  252.                             else:
  253.                                 side_price = -menu[side]
  254.                     else:
  255.                         if item[0:3] == 'the':
  256.                             item = item[3:].lstrip()
  257.                         item = item[0:-1].strip()
  258.                     if not item in menu:
  259.                         success = False
  260.                         errorMessage = 'Menu item "'+item+'" was not declared in the menu.'
  261.                     else:
  262.                         dish_price = menu[item]+side_price
  263.                 #Assign value to person
  264.                 if success:
  265.                     modifier = split_line[0].strip()
  266.                     if not modifier:
  267.                         people[person] = dish_price
  268.                     elif modifier == 'not':
  269.                         people[person] -= dish_price
  270.                     elif modifier == 'also':
  271.                         people[person] += dish_price
  272.                     else:
  273.                         success = False
  274.                         errorMessage = '"' + modifier + '" is not a valid modifier for a "would like" command. Valid modifiers are "would not like" and "would also like".'
  275.                     people[person] %= 256
  276.  
  277.         #Person N will pay for his order!
  278.         elif 'Person ' in line and ' will pay for his order!' in line:
  279.             split_line = line.split('Person ')
  280.             if split_line[0]:
  281.                 success = False
  282.                 errorMessage = 'Invalid syntax.'
  283.             else:
  284.                 split_line = split_line[1].split(' will pay for his order!')
  285.                 person = split_line[0].strip()
  286.                 for digit in person:
  287.                     if not digit in digits:
  288.                         success = False
  289.                         errorMessage = 'Person must be a positive whole number.'
  290.                         break
  291.                 #Parse person
  292.                 if success:
  293.                     person = int(person)
  294.                     if person == 0:
  295.                         success = False
  296.                         errorMessage = 'Person must be greater than 0'
  297.                     elif person not in people:
  298.                         people[person] = 0
  299.                 #Print person value:
  300.                 if success:
  301.                     sys.stdout.write(str(unichr(people[person])))
  302.         #Person N needs X dollars more/less for his order!
  303.         elif 'Person 'in line and ' needs ' in line and (' dollars ' in line or ' dollar ' in line) and ' for his order!' in line and (' more ' in line or ' less 'in line):
  304.             split_line = line.split('Person ')
  305.             if split_line[0]:
  306.                 success = False
  307.                 errorMessage = 'Invalid syntax.'
  308.             else:
  309.                 adding = ' more ' in line
  310.                 split_line[1] = split_line[1].replace(' more ',' ').replace(' less ',' ')
  311.                 person = split_line[1].split(' needs ')[0].strip()
  312.                 if ' dollars ' in line:
  313.                     money = split_line[1].split(' needs ')[1].split(' dollars ')[0].strip()
  314.                 else:
  315.                     money = split_line[1].split(' needs ')[1].split(' dollar ')[0].strip()
  316.                
  317.                 for digit in person:
  318.                     if not digit in digits:
  319.                         success = False
  320.                         errorMessage = 'Person must be a positive whole number.'
  321.                         break
  322.                 for digit in money:
  323.                     if not digit in digits:
  324.                         success = False
  325.                         errorMessage = 'dollars must be a positive whole number.'
  326.                         break
  327.                 #Parse person
  328.                 if success:
  329.                     person = int(person)
  330.                     if person == 0:
  331.                         success = False
  332.                         errorMessage = 'Person must be greater than 0'
  333.                     elif person not in people:
  334.                         people[person] = 0
  335.                 #Parse money and assign value
  336.                 if success:
  337.                     if adding:
  338.                         money = int(money)
  339.                     else:
  340.                         money = -1 * int(money)
  341.                     if ' dollar ' in line and not money == 1:
  342.                         warningMessage = 'Using "dollar" to reference a non singular amount of money.'
  343.                     elif ' dollars ' in line and money == 1:
  344.                         warningMessage = 'Using "dollars" to reference a single dollar.'
  345.                     people[person] += money
  346.  
  347.         elif 'OK, what should Person ' in line and ' get?' in line:
  348.             person = line.replace('OK, what should Person ','').replace(' get?','').strip()
  349.             for digit in person:
  350.                 if not digit in digits:
  351.                     success = False
  352.                     errorMessage = 'Person must be a positive whole number.'
  353.                     break
  354.             if success:
  355.                 person = int(person)
  356.                 if person == 0:
  357.                     success = False
  358.                     errorMessage = 'Person must be greater than 0'
  359.             if success:
  360.                 people[person] = ord(getch())
  361.         elif 'OK, how much money should Person ' in line and ' have?' in line:
  362.             person = line.replace('OK, how much money should Person ','').replace(' have?','').strip()
  363.             for digit in person:
  364.                 if not digit in digits:
  365.                     success = False
  366.                     errorMessage = 'Person must be a positive whole number.'
  367.                     break
  368.             if success:
  369.                 person = int(person)
  370.                 if person == 0:
  371.                     success = False
  372.                     errorMessage = 'Person must be greater than 0'
  373.             if success:
  374.                 people[person] = int(raw_input().strip())
  375.         elif 'Let\'s just do this until Person ' in line and ' has no more money!' in line:
  376.             if line_number not in for_dict:
  377.                 for_stack = []
  378.                 for cur_line_number in range(line_number,len(commands)):
  379.                     cur_line = commands[cur_line_number]
  380.                     if 'Let\'s just do this until Person ' in cur_line and ' has no more money!' in cur_line:
  381.                         for_stack.append(cur_line_number)
  382.                     elif 'Person ' in cur_line and ' has no more money!' in cur_line:
  383.                         for_start = for_stack.pop()
  384.                         for_end = cur_line_number
  385.                         for_dict[for_start] = for_end
  386.                         end_for_dict[for_end] = for_start
  387.                         if not for_stack:
  388.                             break
  389.                 if for_stack:
  390.                     success = False
  391.                     errorMessage = 'This loop has no end!'
  392.             if success:
  393.                 person = line.replace('Let\'s just do this until Person ','').replace(' has no more money!','').strip()
  394.                 for digit in person:
  395.                     if not digit in digits:
  396.                         success = False
  397.                         errorMessage = 'Person must be a positive whole number.'
  398.                         break
  399.             if success:
  400.                 person = int(person)
  401.                 if person == 0:
  402.                     success = False
  403.                     errorMessage = 'Person must be greater than 0'
  404.             if success and people[person] == 0:
  405.                 line_number = for_dict[line_number]
  406.  
  407.         elif 'Person ' in line and ' has no more money!' in line:
  408.             if line_number not in end_for_dict:
  409.                 success = False
  410.                 errorMessage = 'This loop has no start!'
  411.             else:
  412.                 line_number = end_for_dict[line_number]-1
  413.         elif line == 'Just wait while we decide...':
  414.             raw_input()
  415.        
  416.         elif 'OK, that will be ' in line and '. Thanks for coming!' in line:
  417.             declarationState = 'finished'
  418.         else:
  419.             success = False
  420.             errorMessage = 'Unknown command, check the syntax.'
  421.     else:
  422.         break
  423.     if not success:
  424.         declarationState = 'error'
  425.         break
  426.     if showWarnings and warningMessage:
  427.         printWarningMessage(filename,line_number,line,warningMessage)
  428.     line_number += 1
  429. #end while
  430.  
  431. if declarationState == 'error':
  432.     printErrorMessage(filename,line_number,line,errorMessage)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement