Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
muddyfish committed Feb 18, 2016
0 parents commit ed0769d
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
20 changes: 20 additions & 0 deletions ast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python

import nodes

class AST(object):
def __init__(self, code):
self.nodes = []
while code != "":
code = self.add_node(code)
print self.nodes

def add_node(self, code):
for name in nodes.nodes:
node = nodes.nodes[name]
new_code, new_node = node.accepts(code)
if new_code is not None:
assert(new_node is not None)
self.nodes.append(new_node)
return new_code
raise SyntaxError("No nodes will accept code: %s"%(code))
6 changes: 6 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/usr/bin/env python

import ast
import nodes

ast.AST('p123p"')
88 changes: 88 additions & 0 deletions nodes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env python

nodes = {}

class MetaNode(type):
def __new__(cls, name, bases, attrs):
new = super(MetaNode, cls).__new__(cls, name, bases, attrs)
if bases[0] is not object:
nodes[name] = new
return new

class Node(object):
__metaclass__ = MetaNode
char = ""
func = lambda: None
args = 0
results = 0

def __init__(self):
print self

def __repr__(self):
return self.__class__.__name__

def __call__(self, *args):
assert(len(args) == self.args)
ret = func(*args)
assert(len(ret) == self.results)
return ret

@classmethod
def accepts(cls, code):
if code[0] == cls.char:
return code[1:], cls()
return None, None

class PrintFunc(Node):
char = "p"
args = 1
results = 1
def func(arg):
print arg
return arg

class NumericLiteral(Node):
args = 0
results = 1

def __init__(self, digits):
self.func = lambda: digits

def __repr__(self):
return "%s: %d"%(self.__class__.__name__, self.func())

@classmethod
def accepts(cls, code):
digits = ""
while code[0].isdigit():
digits += code[0]
code = code[1:]
if digits:
return code, cls(int(digits))
return None, None

class StringLiteral(Node):
args = 0
results = 1

def __init__(self, string):
self.func = lambda: string

def __repr__(self):
return "%s: %r"%(self.__class__.__name__, self.func())

@classmethod
def accepts(cls, code):
string = None
if code[0] == '"':
string = ""
if len(code) != 1:
code = code[1:]
while len(code) != 0 and code[0] != '"':
string += code[0]
code = code[1:]
if len(code) != 0: code = code[1:]
if string is not None:
return code, cls(string)
return None, None

0 comments on commit ed0769d

Please sign in to comment.