aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2012-12-26 23:37:41 +0200
committerJussi Pakkanen <jpakkane@gmail.com>2012-12-26 23:37:41 +0200
commit4dbe7f6f34149502531c60587b565bdb3314b048 (patch)
treea32ae123dfc2b8f7a92ab6032eb7ce071c84b0c0
parentbc249bc697aad332c70635dc78c77737be7577bb (diff)
downloadmeson-4dbe7f6f34149502531c60587b565bdb3314b048.zip
meson-4dbe7f6f34149502531c60587b565bdb3314b048.tar.gz
meson-4dbe7f6f34149502531c60587b565bdb3314b048.tar.bz2
Can call functions and print text.
-rwxr-xr-xinterpreter.py39
-rw-r--r--nodes.py6
-rwxr-xr-xparser.py3
3 files changed, 44 insertions, 4 deletions
diff --git a/interpreter.py b/interpreter.py
index 91b6a7c..4ea9f4c 100755
--- a/interpreter.py
+++ b/interpreter.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()
diff --git a/nodes.py b/nodes.py
index af52a30..6305d31 100644
--- a/nodes.py
+++ b/nodes.py
@@ -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())
diff --git a/parser.py b/parser.py
index e3da802..b376dbf 100755
--- a/parser.py
+++ b/parser.py
@@ -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)