Skip to content
This repository has been archived by the owner on Aug 6, 2023. It is now read-only.

Commit

Permalink
Made certain strings be analysed as code (e.g. isNil).
Browse files Browse the repository at this point in the history
Fixed #29
  • Loading branch information
LordGolias committed Jan 2, 2018
1 parent 68b6e95 commit 23aa472
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
14 changes: 14 additions & 0 deletions sqf/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,20 @@ def execute_single(self, statement):
if case_found:
# if exact match, we run the expression.
if case_found.is_match(values):
# parse and execute the string that is code (to count usage of variables)
if case_found.keyword == Keyword('isnil') and type(values[1]) == String or \
case_found.keyword == Keyword('configClasses'):
code_position = {'isnil': 1, 'configclasses': 0}[case_found.keyword.unique_token]
extra_scope = {'isnil': None, 'configclasses': {'_x': Anything()}}[case_found.keyword.unique_token]
try:
code = Code([parse(values[code_position].value)])
code.position = values[code_position].position
self.execute_code(code, extra_scope=extra_scope)
except SQFParserError as e:
self.exceptions.append(
SQFParserError(values[code_position].position,
'Error while parsing a string to code: %s' % e.message))
# finally, execute the statement
outcome = case_found.execute(values, self)
elif len(possible_expressions) == 1 or all_equal([x.return_type for x in possible_expressions]):
return_type = possible_expressions[0].return_type
Expand Down
27 changes: 27 additions & 0 deletions tests/test_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -1348,3 +1348,30 @@ def test_with_globals(self):
code = 'private _x = ""; AF(_x)'
analyzer = analyze(parse(code))
self.assertEqual(analyzer.exceptions, [])


class StringAsCodeFunctions(TestCase):
"""
Tests functions that are passed a string which is compiled to code.
"""
def test_isNil(self):
code = 'private _var = A getVariable "x"; x = isNil "_var";'
analyzer = analyze(parse(code))
self.assertEqual(len(analyzer.exceptions), 0)

def test_isNil_undefined(self):
code = 'x = isNil "_var";'
analyzer = analyze(parse(code))
self.assertEqual(len(analyzer.exceptions), 1)

def test_isNil_error(self):
code = 'x = isNil "(_var";'
analyzer = analyze(parse(code))
self.assertEqual(len(analyzer.exceptions), 1)
self.assertTrue('Parenthesis "(" not closed' in analyzer.exceptions[0].message)

def test_configClass(self):
code = 'private _defaultCrew = getText (configFile >> "cfgVehicles" >> "All" >> "crew");' \
'"isClass _x && {getNumber (_x >> \'scope\') == 2} && {getText (_x >> \'crew\') != _defaultCrew}" configClasses (configFile >> "cfgVehicles")'
analyzer = analyze(parse(code))
self.assertEqual(len(analyzer.exceptions), 0)

0 comments on commit 23aa472

Please sign in to comment.