Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- def init_state():
- return {
- 'tokens': [],
- 'pos': 0,
- 'codes': [],
- 'branch': [],
- 'words': {},
- 'vars': {},
- 'end': False
- }
- def compile(state, tokens):
- state['tokens'].extend(tokens)
- if state['codes'] and state['codes'][-1] == 'END':
- state['codes'].pop()
- state['end'] = False
- while not state['end']:
- run(state)
- after_last_ret = max(i for i, v in enumerate((';', *state['codes'])) if v == ';')
- return state['codes'], after_last_ret, len(state['vars'])
- def run(state):
- if state['pos'] == len(state['tokens']):
- state['codes'].append('END')
- state['end'] = True
- return
- token = state['tokens'][state['pos']]
- if is_int(token):
- run_int(state, token)
- elif token in primitives:
- run_primitive(state, token)
- elif token in state['words']:
- run_word(state, token)
- elif token in state['vars']:
- run_var(state, token)
- state['pos'] += 1
- def is_int(s):
- try:
- int(s)
- except ValueError:
- return False
- return True
- def run_int(state, token):
- state['codes'].extend(('PUSH', int(token)))
- def run_if(state):
- state['branch'].append(len(state['codes']) + 1)
- state['codes'].extend(('IF', None))
- def run_else(state):
- if_jump = state['branch'].pop()
- code_len = len(state['codes'])
- state['codes'][if_jump] = code_len + 2
- state['branch'].append(code_len + 1)
- state['codes'].extend(('ELSE', None))
- def run_then(state):
- else_jump = state['branch'].pop()
- code_len = len(state['codes'])
- state['codes'][else_jump] = code_len + 1
- state['codes'].append('THEN')
- def run_do(state):
- state['branch'].append(len(state['codes']) + 1)
- state['codes'].append('DO')
- def run_loop(state):
- do_pos = state['branch'].pop()
- state['codes'].extend(('LOOP', do_pos))
- def run_def(state):
- word = state['tokens'][state['pos'] + 1]
- state['words'][word] = len(state['codes'])
- state['tokens'][state['pos'] + 1] = ''
- def run_variable(state):
- var = state['tokens'][state['pos'] + 1]
- if var not in state['vars']:
- state['vars'][var] = len(state['vars'])
- state['tokens'][state['pos'] + 1] = ''
- primitives = {
- 'IF': run_if,
- 'ELSE': run_else,
- 'THEN': run_then,
- 'DO': run_do,
- 'LOOP': run_loop,
- 'VARIABLE': run_variable,
- ':': run_def,
- ';': lambda s: s['codes'].append(';'),
- '+': lambda s: s['codes'].append('+'),
- '.': lambda s: s['codes'].append('.'),
- 'I': lambda s: s['codes'].append('I'),
- 'CR': lambda s: s['codes'].append('CR'),
- '@': lambda s: s['codes'].append('@'),
- '!': lambda s: s['codes'].append('!'),
- }
- def run_primitive(state, token):
- primitives[token](state)
- def run_word(state, token):
- state['codes'].extend(('CALL', state['words'][token]))
- def run_var(state, token):
- state['codes'].extend(('PUSH', state['vars'][token]))
Add Comment
Please, Sign In to add comment