Skip to content

Instantly share code, notes, and snippets.

@Son-Guhun
Created April 2, 2019 19:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Son-Guhun/6687825632cf6d509de248ce4eca915b to your computer and use it in GitHub Desktop.
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
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