Skip to content

Instantly share code, notes, and snippets.

@mr1337357
Created September 23, 2016 00:44
Show Gist options
  • Save mr1337357/cdf903c19eb68f9c5328e9f121b3325b to your computer and use it in GitHub Desktop.
Save mr1337357/cdf903c19eb68f9c5328e9f121b3325b to your computer and use it in GitHub Desktop.
language
def dup ( a |
| a a )
def drop ( a |
| )
def swap ( a b |
| a b )
def * ( a b |
mac cpy ( <b if <a <b -1 + >b cpy end )
mac sum ( count -1 + if + sum end )
cpy sum >a
| a )
mac not (
0 =
)
from collections import deque
import os
from copy import copy
class scope:
def __init__(self,parent=None):
self.parent=parent
self.content={}
def __getitem__(self,name):
if name in self.content:
return self.content[name]
if self.parent and name in self.parent:
return self.parent[name]
return None
def __setitem__(self,name,value):
self.content[name] = value
def __contains__(self,name):
if name in self.content or self.parent and name in self.parent:
return True
return False
def __repr__(self):
out = '{\n'
out += '\n'.join([key+': '+repr(self.content[key]) for key in self.content])
out += '\n}\n => \n'
out += repr(self.parent)
return out
globalvars = scope()
globalstack = []
class mac:
def __init__(self,words):
if words.popleft() != '(':
raise Exception('no macro contents')
self.code=deque()
while words[0] != ')':
self.code.appendleft(words.popleft())
words.popleft()
def __call__(self,context,stack):
interpret(reversed(self.code),context,stack)
def __repr__(self):
out = 'mac ( '
out += ' '.join([repr(code) for code in self.code])
out += ' )'
return out
class fn:
def __init__(self,words):
if words.popleft() != '(':
raise Exception('no function contents')
self.args=[]
self.code=deque()
self.rets=[]
while words[0] != '|':
self.args.append(words.popleft())
words.popleft()
while words[0] != '|':
self.code.append(words.popleft())
words.popleft()
while words[0] != ')':
self.rets.append(words.popleft())
words.popleft()
def __call__(self,context,stack):
newcontext=scope(context)
newstack = []
for name in self.args:
newcontext[name]=stack.pop()
interpret(copy(self.code),newcontext,newstack)
for name in self.rets:
stack.append(newcontext[name])
def __repr__(self):
out = 'fn ( '
out += ' '.join([repr(arg) for arg in self.args])
out += ' | '
out += ' '.join([repr(code) for code in self.code])
out += ' | '
out += ' '.join([repr(ret) for ret in self.rets])
out += ' )'
return out
def interpret(queue,context,stack):
if isinstance(queue,str):
queue=deque(queue.split())
while len(queue):
word = queue.popleft()
if word == 'def':
name = queue.popleft()
context[name]=fn(queue)
elif word == 'mac':
name = queue.popleft()
context[name]=mac(queue)
elif word == 'if':
if stack.pop() == 0:
while queue.popleft() != 'end':
pass
elif word[0] == '<':
stack.append(context[word[1:]])
elif word[0] == '>':
context[word[1:]] = stack.pop()
elif word in context:
val = context[word]
if isinstance(val,mac):
queue.extendleft(val.code)
elif callable(val):
val(context,stack)
try:
stack.append(int(word))
except:
pass
def printfcn(context,stack):
print stack.pop()
def dump(context,stack):
print '[',
for item in stack:
print item,
print ']'
#print context
globalvars['.'] = printfcn
globalvars['='] = lambda context,stack: stack.append(1 if stack.pop() == stack.pop() else 0)
globalvars['+'] = lambda context,stack: stack.append(stack.pop()+stack.pop())
globalvars['count'] = lambda context,stack: stack.append(len(stack))
globalvars['dump'] = dump
#interpret('def dup ( a | | a a ) def swap ( a b | | a b )',globalvars,globalstack)
try:
with open(os.path.expanduser('~/.lang.init'),'r') as initfile:
interpret(' '.join(initfile.readlines()),globalvars,globalstack)
except Exception as e:
print 'no initfile' + repr(e)
pass
import sys
if len(sys.argv) > 1:
try:
with open(sys.argv[1],'r') as infile:
interpret(' '.join(infile.readlines()),globalvars,globalstack)
except:
pass
else:
while True:
interpret(raw_input('LANG: '),globalvars,globalstack)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment