diff options
-rwxr-xr-x | interpreter.py | 69 | ||||
-rwxr-xr-x | shellgenerator.py | 1 | ||||
-rw-r--r-- | test cases/24 target arg/builder.txt | 8 | ||||
-rw-r--r-- | test cases/24 target arg/func.c | 9 | ||||
-rw-r--r-- | test cases/24 target arg/prog.cc | 13 |
5 files changed, 86 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)) diff --git a/shellgenerator.py b/shellgenerator.py index ad375b2..863e06c 100755 --- a/shellgenerator.py +++ b/shellgenerator.py @@ -210,6 +210,7 @@ echo Run compile.sh before this or bad things will happen. commands = [] commands += compiler.get_exelist() commands += self.build.get_global_flags(compiler) + commands += target.get_extra_args(compiler.get_language()) commands += compiler.get_debug_flags() commands += compiler.get_std_warn_flags() commands += compiler.get_compile_only_flags() diff --git a/test cases/24 target arg/builder.txt b/test cases/24 target arg/builder.txt new file mode 100644 index 0000000..9c0b995 --- /dev/null +++ b/test cases/24 target arg/builder.txt @@ -0,0 +1,8 @@ +project('local arg test', 'c++', 'c') + +exe1 = executable('prog', 'prog.cc', 'func.c') + +exe1.add_compiler_args('c', '-DCTHING') +exe1.add_compiler_args('c++', '-DCXXTHING') + +add_test('prog1', exe1) diff --git a/test cases/24 target arg/func.c b/test cases/24 target arg/func.c new file mode 100644 index 0000000..d8a509a --- /dev/null +++ b/test cases/24 target arg/func.c @@ -0,0 +1,9 @@ +#ifndef CTHING +#error "Local argument not set" +#endif + +#ifdef CXXTHING +#error "Wrong local argument set" +#endif + +int func() { return 0; } diff --git a/test cases/24 target arg/prog.cc b/test cases/24 target arg/prog.cc new file mode 100644 index 0000000..cc36ae0 --- /dev/null +++ b/test cases/24 target arg/prog.cc @@ -0,0 +1,13 @@ +#ifdef CTHING +#error "Wrong local argument set" +#endif + +#ifndef CXXTHING +#error "Local argument not set" +#endif + +extern "C" int func(); + +int main(int argc, char **argv) { + return func(); +} |