diff options
Diffstat (limited to 'interpreter.py')
-rwxr-xr-x | interpreter.py | 69 |
1 files changed, 55 insertions, 14 deletions
diff --git a/interpreter.py b/interpreter.py index e74030c..d63cb58 100755 --- a/interpreter.py +++ b/interpreter.py @@ -17,7 +17,7 @@ import parser import nodes import environment -import os +import os, sys, platform class InterpreterException(Exception): pass @@ -38,6 +38,25 @@ class InterpreterObject(): return self.methods[method_name](args) raise InvalidCode('Unknown method "%s" in object.' % method_name) + +# This currently returns data for the current environment. +# It should return info for the target host. +class Host(InterpreterObject): + + def __init__(self): + InterpreterObject.__init__(self) + + def get_ptrsize(self): + if sys.maxsize > 2**32: + return 64 + return 32 + + def get_name(self): + return platform.system().lower() + + def is_little_endian(self): + return sys.byteorder == 'little' + class IncludeDirs(InterpreterObject): def __init__(self, curdir, dirs): InterpreterObject.__init__(self) @@ -132,15 +151,20 @@ class BuildTarget(InterpreterObject): 'install': self.install_method, 'pch' : self.pch_method, 'add_include_dirs': self.add_include_dirs_method, + 'add_compiler_args' : self.add_compiler_args_method, }) self.link_targets = [] self.filename = 'no_name' self.need_install = False self.pch = [] + self.extra_args = {} def get_filename(self): return self.filename - + + def get_extra_args(self, language): + return self.extra_args.get(language, []) + def get_dependencies(self): return self.link_targets @@ -199,6 +223,17 @@ class BuildTarget(InterpreterObject): if not isinstance(a, IncludeDirs): raise InvalidArguments('Include directory to be added is not an include directory object.') self.include_dirs += args + + def add_compiler_args_method(self, args): + for a in args: + if not isinstance(a, str): + raise InvalidArguments('A non-string passed to compiler args.') + language = args[0] + flags = args[1:] + if language in self.extra_args: + self.extra_args[language] += flags + else: + self.extra_args[language] = flags class Executable(BuildTarget): def __init__(self, name, subdir, sources, environment): @@ -244,6 +279,8 @@ class Interpreter(): self.ast = parser.build_ast(code) self.sanity_check_ast() self.variables = {} + self.builtin = {} + self.builtin['host'] = Host() self.environment = build.environment self.build_func_dict() self.subdir = '' @@ -292,6 +329,18 @@ class Interpreter(): self.evaluate_statement(cur) i += 1 # In THE FUTURE jump over blocks and stuff. + def get_variable(self, varname): + if varname in self.builtin: + return self.builtin[varname] + if varname in self.variables: + return self.variables[varname] + raise InvalidCode('Line %d: unknown variable "%s".' % varname) + + def set_variable(self, varname, variable): + if varname in self.builtin: + raise InvalidCode('Tried to overwrite internal variable "%s"' % varname) + self.variables[varname] = variable + def evaluate_statement(self, cur): if isinstance(cur, nodes.FunctionCall): return self.function_call(cur) @@ -306,10 +355,7 @@ class Interpreter(): elif isinstance(cur, nodes.IfStatement): return self.evaluate_if(cur) elif isinstance(cur, nodes.AtomStatement): - varname = cur.get_value() - if varname in self.variables: - return self.variables[varname] - raise InvalidCode('Line %d: unknown variable "%s".' % (cur.lineno(), varname)) + return self.get_variable(cur.get_value()) elif isinstance(cur, nodes.Comparison): return self.evaluate_comparison(cur) elif isinstance(cur, nodes.ArrayStatement): @@ -459,7 +505,6 @@ class Interpreter(): name = args[0] sources = [] for s in args[1:]: - print(s) if not self.environment.is_header(s): sources.append(s) if len(sources) == 0: @@ -498,7 +543,7 @@ class Interpreter(): raise InvalidCode('Line %d: Can not assign None to variable.' % node.lineno()) if not self.is_assignable(value): raise InvalidCode('Line %d: Tried to assign an invalid value to variable.' % node.lineno()) - self.variables[var_name] = value + self.set_variable(var_name, value) return value def reduce_arguments(self, args): @@ -506,9 +551,7 @@ class Interpreter(): reduced = [] for arg in args.arguments: if isinstance(arg, nodes.AtomExpression) or isinstance(arg, nodes.AtomStatement): - if arg.value not in self.variables: - raise InvalidCode('Line %d: variable "%s" is not set' % (arg.lineno(), arg.value)) - r = self.variables[arg.value] + r = self.get_variable(arg.value) elif isinstance(arg, nodes.StringExpression) or isinstance(arg, nodes.StringStatement): r = arg.get_value() elif isinstance(arg, nodes.FunctionCall): @@ -525,9 +568,7 @@ class Interpreter(): object_name = node.object_name.get_value() method_name = node.method_name.get_value() args = node.arguments - if not object_name in self.variables: - raise InvalidArguments('Line %d: unknown variable "%s".' % (node.lineno(), object_name)) - obj = self.variables[object_name] + obj = self.get_variable(object_name) if not isinstance(obj, InterpreterObject): raise InvalidArguments('Line %d: variable "%s" is not callable.' % (node.lineno(), object_name)) return obj.method_call(method_name, self.reduce_arguments(args)) |