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

Commit

Permalink
Merge 408695a into a171ffe
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentBenet committed Jun 8, 2021
2 parents a171ffe + 408695a commit 985a54b
Show file tree
Hide file tree
Showing 16 changed files with 303 additions and 104 deletions.
65 changes: 37 additions & 28 deletions build_database_with_returns.py
Expand Up @@ -4,6 +4,7 @@
https://raw.githubusercontent.com/intercept/intercept/master/src/client/headers/client/sqf_pointers_declaration.hpp
"""
import os
import urllib.request

from sqf.interpreter_types import ForType, IfType, SwitchType, WhileType, TryType, WithType
Expand All @@ -14,6 +15,7 @@
# The mapping of SQF types to our types
STRING_TO_TYPE = {
'array': Array,
'hashmap': Array,
'scalar': Number,
'bool': Boolean,
'code': Code,
Expand Down Expand Up @@ -61,11 +63,8 @@


def _parse_type_names(type_names):
# Alternative types separated by _ char
types_names = type_names.split('_')

# Never care about NaN type (covered by scalar)
if 'nan' in types_names:
types_names = type_names.split('_') # Alternative types separated by _ char
if 'nan' in types_names: # Never care about NaN type (covered by scalar)
types_names.remove('nan')

# Remove parts of types that also get split
Expand All @@ -91,8 +90,7 @@ def _parse_return_type_names(return_type_names):
return STRING_TO_TYPE_RETURN[return_type_name]


url = 'https://raw.githubusercontent.com/intercept/intercept/master/src/' \
'client/headers/client/sqf_pointers_declaration.hpp'
url = 'https://raw.githubusercontent.com/intercept/intercept/master/src/client/headers/client/sqf_pointers_declaration.hpp'
data = urllib.request.urlopen(url).read().decode('utf-8').split('\n')


Expand All @@ -101,21 +99,25 @@ def _parse_return_type_names(return_type_names):
if not line.startswith('static '):
continue

print("_" * 50)
sections = line.split('__')
print("sections: " + str(sections))
num_sections = len(sections)

if num_sections not in [4, 5, 6]:
print('Could\'t read line: ', line)
continue

# Name always comes first
op_name = sections[1]
print("op_name: " + str(op_name))

# Return type always comes last (some operators have incorrect values for whatever reason)
if op_name in WRONG_RETURN_TYPES:
return_type = WRONG_RETURN_TYPES[op_name]
else:
return_type = _parse_return_type_names(sections[num_sections-1][:-1])
print("return_type: " + str(return_type))

# Adds any relevant initialization argument for the return type
init_code = ''
Expand All @@ -129,10 +131,7 @@ def _parse_return_type_names(return_type_names):
lhs_type = STRING_TO_TYPE[lhs_type_name]
for rhs_type_name in _parse_type_names(sections[3]):
rhs_type = STRING_TO_TYPE[rhs_type_name]
expression = 'BinaryExpression(' \
'{lhs_type}, ' \
'Keyword(\'{keyword}\'), ' \
'{rhs_type}, {return_type}{init_code})'.format(
expression = 'BinaryExpression({lhs_type}, Keyword(\'{keyword}\'), {rhs_type}, {return_type}{init_code})'.format(
lhs_type=lhs_type.__name__,
keyword=op_name,
rhs_type=rhs_type.__name__,
Expand All @@ -144,11 +143,13 @@ def _parse_return_type_names(return_type_names):
if return_type in TYPE_TO_INIT_ARGS:
init_code = ', action=lambda rhs, i: %s' % TYPE_TO_INIT_ARGS[return_type]

for rhs_type_name in _parse_type_names(sections[2]):
for i, rhs_type_name in enumerate(_parse_type_names(sections[2])):

# if rhs_type_name not in STRING_TO_TYPE:
# continue

rhs_type = STRING_TO_TYPE[rhs_type_name]
expression = 'UnaryExpression(' \
'Keyword(\'{keyword}\'), ' \
'{rhs_type}, {return_type}{init_code})'.format(
expression = 'UnaryExpression(Keyword(\'{keyword}\'), {rhs_type}, {return_type}{init_code})'.format(
keyword=op_name,
rhs_type=rhs_type.__name__,
return_type=return_type.__name__,
Expand All @@ -159,13 +160,11 @@ def _parse_return_type_names(return_type_names):
if return_type in TYPE_TO_INIT_ARGS:
init_code = ', action=lambda i: %s' % TYPE_TO_INIT_ARGS[return_type]

expression = 'NullExpression(' \
'Keyword(\'{keyword}\'), ' \
'{return_type}{init_code})'.format(
keyword=op_name,
return_type=return_type.__name__,
init_code=init_code
)
expression = 'NullExpression(Keyword(\'{keyword}\'), {return_type}{init_code})'.format(
keyword=op_name,
return_type=return_type.__name__,
init_code=init_code
)
expressions.append(expression)

preamble = r'''# This file is generated automatically by `build_database.py`. Change it there.
Expand Down Expand Up @@ -231,9 +230,19 @@ def _parse_return_type_names(return_type_names):
UnaryExpression(Keyword('-'), Number, Number),
'''

import_input = """
from .expressions import BinaryExpression, UnaryExpression, NullExpression
from .types import Keyword, Type, Nothing, Anything, String, Code, Array, Number, Boolean, Namespace, Object, Config, Script, Control, Group, Display, Side, Task, Location, NetObject, DiaryReport, TeamMember
from .interpreter_types import WhileType, ForType, SwitchType, IfType, TryType, WithType
"""

formatted_expressions = ' ' + ',\n '.join(expressions)

with open('sqf/database.py', 'w') as f:
f.write(preamble + '\n\n')
f.write(symbols + ' ')
f.write(',\n '.join(expressions))
f.write('\n]\n')
content = f"""
{import_input}
{symbols}{formatted_expressions}
]
"""
with open(os.path.join(os.path.dirname(__file__), 'sqf/database.py'), 'w') as f:
f.write(content)
24 changes: 12 additions & 12 deletions sqf/analyzer.py
@@ -1,18 +1,18 @@
from copy import deepcopy

from sqf.types import Statement, Code, Nothing, Variable, Array, String, Type, File, BaseType, \
from .types import Statement, Code, Nothing, Variable, Array, String, Type, File, BaseType, \
Number, Preprocessor, Script, Anything
from sqf.interpreter_types import InterpreterType, PrivateType, ForType, SwitchType, \
from .interpreter_types import InterpreterType, PrivateType, ForType, SwitchType, \
DefineStatement, DefineResult, IfDefResult
from sqf.keywords import Keyword, PREPROCESSORS
from sqf.expressions import UnaryExpression, BinaryExpression
from sqf.exceptions import SQFParserError, SQFWarning
from sqf.base_interpreter import BaseInterpreter
from sqf.database import EXPRESSIONS
from sqf.common_expressions import COMMON_EXPRESSIONS, ForEachExpression, ElseExpression
from sqf.expressions_cache import values_to_expressions, build_database
from sqf.parser_types import Comment
from sqf.parser import parse
from .keywords import Keyword, PREPROCESSORS
from .expressions import UnaryExpression, BinaryExpression
from .exceptions import SQFParserError, SQFWarning
from .base_interpreter import BaseInterpreter
from .database import EXPRESSIONS
from .common_expressions import COMMON_EXPRESSIONS, ForEachExpression, ElseExpression
from .expressions_cache import values_to_expressions, build_database
from .parser_types import Comment
from .parser import parse


def all_equal(iterable):
Expand Down Expand Up @@ -261,7 +261,7 @@ def assign(self, lhs, rhs_v):
rhs_t = Anything
elif lhs_t != rhs_t and self.delete_scope_level >= scope.level:
rhs_t = Anything

scope[lhs_name] = rhs_t()

if scope.level == 0 and lhs_name.startswith('_'):
Expand Down
16 changes: 8 additions & 8 deletions sqf/base_interpreter.py
@@ -1,7 +1,7 @@
from sqf.types import Statement, Code, Nothing, Anything, Variable, Array, String, Type, File
from sqf.keywords import Keyword
from sqf.exceptions import SQFParserError, SQFWarning
import sqf.namespace
from .types import Statement, Code, Nothing, Anything, Variable, Array, String, Type, File
from .keywords import Keyword
from .exceptions import SQFParserError, SQFWarning
from . import namespace


class BaseInterpreter:
Expand All @@ -12,10 +12,10 @@ class BaseInterpreter:

def __init__(self, all_vars=None):
self._namespaces = {
'uinamespace': sqf.namespace.Namespace('uinamespace'),
'parsingnamespace': sqf.namespace.Namespace('parsingnamespace'),
'missionnamespace': sqf.namespace.Namespace('missionnamespace', all_vars),
'profilenamespace': sqf.namespace.Namespace('profilenamespace')
'uinamespace': namespace.Namespace('uinamespace'),
'parsingnamespace': namespace.Namespace('parsingnamespace'),
'missionnamespace': namespace.Namespace('missionnamespace', all_vars),
'profilenamespace': namespace.Namespace('profilenamespace')
}

self.current_namespace = self.namespace('missionnamespace')
Expand Down
4 changes: 2 additions & 2 deletions sqf/client.py
@@ -1,5 +1,5 @@
from sqf.interpreter import Interpreter, interpret
from sqf.types import Code, Array, String
from .interpreter import Interpreter, interpret
from .types import Code, Array, String


class Client:
Expand Down
6 changes: 3 additions & 3 deletions sqf/common_expressions.py
@@ -1,6 +1,6 @@
from sqf.types import Keyword, Number, Array, Code, Type, Boolean, String, Namespace
from sqf.interpreter_types import WhileType, ForType, ForSpecType, SwitchType, IfType, ElseType, TryType, WithType
from sqf.expressions import BinaryExpression, UnaryExpression
from .types import Keyword, Number, Array, Code, Type, Boolean, String, Namespace
from .interpreter_types import WhileType, ForType, ForSpecType, SwitchType, IfType, ElseType, TryType, WithType
from .expressions import BinaryExpression, UnaryExpression


class WhileExpression(UnaryExpression):
Expand Down

0 comments on commit 985a54b

Please sign in to comment.