Can call functions and print text.

pull/15/head
Jussi Pakkanen 12 years ago
parent bc249bc697
commit 4dbe7f6f34
  1. 39
      interpreter.py
  2. 6
      nodes.py
  3. 3
      parser.py

@ -28,6 +28,7 @@ class Interpreter():
def __init__(self, code):
self.ast = parser.build_ast(code)
self.sanity_check_ast()
self.project = None
def sanity_check_ast(self):
if not isinstance(self.ast, nodes.CodeBlock):
@ -37,8 +38,42 @@ class Interpreter():
first = self.ast.get_statements()[0]
if not isinstance(first, nodes.FunctionCall) or first.get_function_name() != 'project':
raise InvalidCode('First statement must be a call to project')
def run(self):
i = 0
statements = self.ast.get_statements()
while i < len(statements):
cur = statements[i]
if isinstance(cur, nodes.FunctionCall):
self.function_call(cur)
else:
print("Unknown statement in line %d." % cur.lineno())
i += 1
def function_call(self, node):
func_name = node.get_function_name()
if func_name == 'project':
args = node.arguments.arguments
if len(args) != 1:
raise InvalidCode('Project() must have one and only one argument.')
if not isinstance(args[0], nodes.StringStatement):
raise InvalidCode('Project() argument must be a string.')
if self.project is not None:
raise InvalidCode('Second call to project() on line %d.' % node.lineno())
self.project = args[0].get_string()
print("Project name is %s." % self.project)
elif func_name == 'message':
args = node.arguments.arguments
if len(args) != 1:
raise InvalidCode('Message() must have only one argument')
if not isinstance(args[0], nodes.StringStatement):
raise InvalidCode('Argument to Message() must be a string')
print('Message: %s' % args[0].get_string())
if __name__ == '__main__':
code = "project('myawesomeproject')"
code = """project('myawesomeproject')
message('I can haz text printed out?')
message('It workses!')
"""
i = Interpreter(code)
i.run()

@ -48,6 +48,9 @@ class StringStatement(Statement):
assert(type(value) == type(''))
Statement.__init__(self, lineno)
self.value = value
def get_string(self):
return self.value
class FunctionCall(Statement):
def __init__(self, func_name, arguments, lineno):
@ -90,6 +93,9 @@ class Arguments(Statement):
def prepend(self, statement):
self.arguments = [statement] + self.arguments
def __len__(self):
return len(self.arguments)
def statement_from_expression(expr):
if isinstance(expr, AtomExpression):
return AtomStatement(expr.value, expr.lineno())

@ -150,8 +150,7 @@ def test_parser():
print(build_ast(code))
def build_ast(code):
if not code.endswith('\n'):
code = code + '\n'
code = code.rstrip() + '\n'
lex.lex()
parser = yacc.yacc()
result = parser.parse(code)

Loading…
Cancel
Save