Guest User

Untitled

a guest
Jul 18th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.00 KB | None | 0 0
  1. def init_state():
  2. return {
  3. 'tokens': [],
  4. 'pos': 0,
  5. 'codes': [],
  6. 'branch': [],
  7. 'words': {},
  8. 'vars': {},
  9. 'end': False
  10. }
  11.  
  12. def compile(state, tokens):
  13. state['tokens'].extend(tokens)
  14. if state['codes'] and state['codes'][-1] == 'END':
  15. state['codes'].pop()
  16. state['end'] = False
  17.  
  18. while not state['end']:
  19. run(state)
  20.  
  21. after_last_ret = max(i for i, v in enumerate((';', *state['codes'])) if v == ';')
  22. return state['codes'], after_last_ret, len(state['vars'])
  23.  
  24. def run(state):
  25. if state['pos'] == len(state['tokens']):
  26. state['codes'].append('END')
  27. state['end'] = True
  28. return
  29.  
  30. token = state['tokens'][state['pos']]
  31.  
  32. if is_int(token):
  33. run_int(state, token)
  34. elif token in primitives:
  35. run_primitive(state, token)
  36. elif token in state['words']:
  37. run_word(state, token)
  38. elif token in state['vars']:
  39. run_var(state, token)
  40.  
  41. state['pos'] += 1
  42.  
  43.  
  44. def is_int(s):
  45. try:
  46. int(s)
  47. except ValueError:
  48. return False
  49. return True
  50.  
  51. def run_int(state, token):
  52. state['codes'].extend(('PUSH', int(token)))
  53.  
  54.  
  55. def run_if(state):
  56. state['branch'].append(len(state['codes']) + 1)
  57. state['codes'].extend(('IF', None))
  58.  
  59. def run_else(state):
  60. if_jump = state['branch'].pop()
  61. code_len = len(state['codes'])
  62. state['codes'][if_jump] = code_len + 2
  63. state['branch'].append(code_len + 1)
  64. state['codes'].extend(('ELSE', None))
  65.  
  66. def run_then(state):
  67. else_jump = state['branch'].pop()
  68. code_len = len(state['codes'])
  69. state['codes'][else_jump] = code_len + 1
  70. state['codes'].append('THEN')
  71.  
  72. def run_do(state):
  73. state['branch'].append(len(state['codes']) + 1)
  74. state['codes'].append('DO')
  75.  
  76. def run_loop(state):
  77. do_pos = state['branch'].pop()
  78. state['codes'].extend(('LOOP', do_pos))
  79.  
  80. def run_def(state):
  81. word = state['tokens'][state['pos'] + 1]
  82. state['words'][word] = len(state['codes'])
  83. state['tokens'][state['pos'] + 1] = ''
  84.  
  85. def run_variable(state):
  86. var = state['tokens'][state['pos'] + 1]
  87. if var not in state['vars']:
  88. state['vars'][var] = len(state['vars'])
  89. state['tokens'][state['pos'] + 1] = ''
  90.  
  91. primitives = {
  92. 'IF': run_if,
  93. 'ELSE': run_else,
  94. 'THEN': run_then,
  95. 'DO': run_do,
  96. 'LOOP': run_loop,
  97. 'VARIABLE': run_variable,
  98. ':': run_def,
  99. ';': lambda s: s['codes'].append(';'),
  100. '+': lambda s: s['codes'].append('+'),
  101. '.': lambda s: s['codes'].append('.'),
  102. 'I': lambda s: s['codes'].append('I'),
  103. 'CR': lambda s: s['codes'].append('CR'),
  104. '@': lambda s: s['codes'].append('@'),
  105. '!': lambda s: s['codes'].append('!'),
  106. }
  107.  
  108. def run_primitive(state, token):
  109. primitives[token](state)
  110.  
  111. def run_word(state, token):
  112. state['codes'].extend(('CALL', state['words'][token]))
  113.  
  114. def run_var(state, token):
  115. state['codes'].extend(('PUSH', state['vars'][token]))
Add Comment
Please, Sign In to add comment