X-Git-Url: https://code.kerkeslager.com/?p=fur;a=blobdiff_plain;f=interpreter.py;fp=interpreter.py;h=cbcfd4e3dcaf0c787a15f6f880d3be59d685d420;hp=5f71e3b0bf3e95c60f2f65f586bd7161328dfa8c;hb=c9f3ff468993d92c3e32de627f1ac725859c8dd4;hpb=d70666abc2db430300d48691046ada2395b2f0d5 diff --git a/interpreter.py b/interpreter.py index 5f71e3b..cbcfd4e 100644 --- a/interpreter.py +++ b/interpreter.py @@ -1,7 +1,17 @@ +import collections import sys import crossplatform_ir_generation +Symbol = collections.namedtuple( + 'Symbol', + ( + 'name', + ), +) + +SYMBOL_TABLE = {} + class Environment(object): def __init__(self, parent): self.symbols = {} @@ -140,6 +150,16 @@ def interpret(program): assert argument is None sys.exit(0) + elif instruction == 'field': + key = stack.pop() + structure = stack.pop() + sentinel = object() + result = getattr(structure, key.name, sentinel) + + assert result is not sentinel + + stack.append(result) + elif instruction == 'get': index = stack.pop() assert isinstance(argument, int) @@ -182,6 +202,30 @@ def interpret(program): assert argument.endswith('"') stack.append(argument[1:-1].encode('utf-8').decode('unicode_escape')) + elif instruction == 'push_symbol': + assert argument.startswith('sym(') + assert argument.endswith(')') + + result = SYMBOL_TABLE.get(argument) + if not result: + result = Symbol(name=argument[4:-1]) + SYMBOL_TABLE[argument] = result + + stack.append(result) + + elif instruction == 'structure': + kvps = [] + + for i in range(argument): + key = stack.pop() + value = stack.pop() + kvps.append((key.name, value)) + + keys = tuple(reversed(list(k for k,v in kvps))) + result = collections.namedtuple('Structure', keys)(**dict(kvps)) + + stack.append(result) + else: raise Exception('Instruction "{}" not supported (argument {}).'.format( instruction,