Created
April 2, 2019 19:21
-
-
Save Son-Guhun/6687825632cf6d509de248ce4eca915b to your computer and use it in GitHub Desktop.
A constant global variable inline (for types integer, real and boolean) for JASS2 scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
alphabet = 'abcdefghijklmnopqrstuvwxyz' | |
numeric = '1234567890' | |
valid_symbol_chars = { '_', '$' } | |
for letter in alphabet: | |
valid_symbol_chars.add(letter) | |
valid_symbol_chars.add(letter.upper()) | |
for digit in numeric: | |
valid_symbol_chars.add(digit) | |
constants = {} | |
l_vars = set() | |
import sys | |
def starts_with(string, substring): | |
return string[:len(substring)] == substring | |
def get_rlvalues(line): | |
line = line.strip() | |
i = line.find('//') | |
if i != -1: | |
line = line[:i] | |
line = line.split('=') | |
return line | |
def parse_constant(line): | |
rvalue, lvalue = get_rlvalues(line) | |
const ,type, name = rvalue.split() | |
if type in ['integer', 'real', 'boolean']: | |
constants[name] = lvalue.strip() | |
return True | |
return False | |
def parse_local(line): | |
rvalue = get_rlvalues(line)[0] | |
name = rvalue.split()[-1] | |
l_vars.add(name) | |
def parse_parameters(line): | |
params = line[line.find('takes')+len('takes'):line.find('returns')] | |
params = params.strip() | |
if params != 'nothing': | |
params = params.split(',') | |
for i in range(len(params)): | |
params[i] = params[i].strip() | |
params[i] = params[i].split() | |
for type,name in params: | |
l_vars.add(name) | |
def parse(file, out=sys.stdout): | |
in_locals = False | |
in_function = False | |
in_globals = True | |
for line in file: | |
stripped = line.strip() | |
if in_globals: | |
if starts_with(stripped, "constant "): | |
line = parse_line(line) | |
if parse_constant(line): | |
line = '' | |
elif starts_with(stripped, "endglobals"): | |
in_globals = False | |
elif in_locals: | |
if starts_with(stripped, "local"): | |
line = parse_line(line) | |
parse_local(line) | |
elif stripped != '': | |
in_locals = False | |
in_function = True | |
if in_function: | |
if stripped: | |
if starts_with(stripped, "endfunction"): | |
in_locals = False | |
in_function = False | |
l_vars.clear() | |
else: | |
try: | |
line = parse_line(line) | |
except Exception as e: | |
sys.stderr.write(line) | |
raise e | |
else: | |
if starts_with(stripped, 'function') or starts_with(stripped, 'constant function'): | |
in_locals = True | |
if line: | |
out.write(line) | |
def parse_line_impl(line): | |
is_string = False | |
escape = False | |
first_slash = False | |
is_comment = False | |
buffer = [] | |
is_symbol = False | |
noise = [] | |
symbols = [] | |
for char in line: | |
if is_comment: | |
pass | |
elif first_slash and char == '/': | |
is_comment = True | |
elif is_string: | |
if char == '\\': | |
escape = True | |
if char == '"' and not escape: | |
is_string = False | |
symbols.append(''.join(buffer)) | |
buffer.clear() | |
escape = False | |
else: | |
if char == '/': | |
first_slash = True | |
elif char == '"': | |
is_string = True | |
if is_symbol: | |
symbol = ''.join(buffer) | |
if symbol in constants: | |
symbols.append('({})'.format(constants[symbol])) | |
else: | |
symbols.append(symbol) | |
buffer.clear() | |
else: | |
noise.append(''.join(buffer)) | |
buffer.clear() | |
is_symbol = False # will be false, since the string must be followed by a non-symbol | |
elif char in valid_symbol_chars: | |
if not is_symbol: | |
noise.append(''.join(buffer)) | |
buffer.clear() | |
is_symbol = True | |
else: | |
if is_symbol: | |
symbol = ''.join(buffer) | |
if symbol in constants and symbol not in l_vars: | |
symbols.append('({})'.format(constants[symbol])) | |
else: | |
symbols.append(symbol) | |
buffer.clear() | |
is_symbol = False | |
buffer.append(char) | |
noise.append(''.join(buffer)) | |
return noise, symbols | |
def parse_line(line): | |
noise, symbols = parse_line_impl(line) | |
result = [] | |
for i,v in enumerate(symbols): | |
result.append(noise[i]) | |
result.append(v) | |
result.append(noise[-1]) | |
return ''.join(result) #, noise, symbols | |
def do(file='test.j', out=sys.stdout): | |
constants.clear() | |
l_vars.clear() # not needed if the last execution was successful | |
with open(file,'r') as f: | |
parse(f, out) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment