alpine: Move old nml version remains into a separate directory
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 102 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 515 KiB After Width: | Height: | Size: 515 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1,505 +0,0 @@
|
||||
import struct
|
||||
|
||||
import ply.lex
|
||||
import ply.yacc
|
||||
|
||||
OP_ADD = 0x00
|
||||
OP_SUB = 0x01
|
||||
OP_MIN = 0x02
|
||||
OP_MAX = 0x03
|
||||
OP_MINU = 0x04
|
||||
OP_MAXU = 0x05
|
||||
OP_MUL = 0x0A
|
||||
OP_BINAND = 0x0B
|
||||
OP_BINOR = 0x0C
|
||||
OP_BINXOR = 0x0D
|
||||
OP_TSTO = 0x0E
|
||||
OP_INIT = 0x0F
|
||||
OP_PSTO = 0x10
|
||||
OP_ROT = 0x11
|
||||
OP_CMP = 0x12
|
||||
OP_CMPU = 0x13
|
||||
OP_SHL = 0x14
|
||||
OP_SHRU = 0x15
|
||||
OP_SHR = 0x16
|
||||
|
||||
OPERATORS = {
|
||||
OP_ADD: ('{a} + {b}', 5, False),
|
||||
OP_SUB: ('{a} - {b}', 5, True),
|
||||
OP_MIN: ('min({a}, {b})', 7, False),
|
||||
OP_MAX: ('max({a}, {b})', 7, False),
|
||||
OP_MINU: ('minu({a}, {b})', 7, False),
|
||||
OP_MAXU: ('maxu({a}, {b})', 7, False),
|
||||
OP_MUL: ('{a} * {b}', 6, False),
|
||||
OP_BINAND: ('{a} & {b}', 4, True),
|
||||
OP_BINOR: ('{a} | {b}', 4, True),
|
||||
OP_BINXOR: ('{a} ^ {b}', 4, True),
|
||||
OP_TSTO: ('TEMP[{b}] = {a}', 2, True),
|
||||
OP_INIT: (None, 1, False),
|
||||
OP_PSTO: ('PERM[{b}] = {a}', 2, True),
|
||||
OP_ROT: ('rot({a}, {b})', 7, False),
|
||||
OP_CMP: ('cmp({a}, {b})', 7, False),
|
||||
OP_CMPU: ('cmpu({a}, {b})', 7, False),
|
||||
OP_SHL: ('{a} << {b}', 4, True),
|
||||
OP_SHRU: ('{a} u>> {b}', 4, True),
|
||||
OP_SHR: ('{a} >> {b}', 4, True),
|
||||
}
|
||||
|
||||
DEFAULT_INDENT_STR = ' '
|
||||
|
||||
|
||||
def hex_str(s):
|
||||
if isinstance(s, (bytes, memoryview)):
|
||||
return ':'.join('{:02x}'.format(b) for b in s)
|
||||
return ':'.join('{:02x}'.format(ord(c)) for c in s)
|
||||
|
||||
|
||||
class Node:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def _make_node(self, value):
|
||||
if isinstance(value, int):
|
||||
return Value(value)
|
||||
assert isinstance(value, Node)
|
||||
return value
|
||||
|
||||
def __add__(self, other):
|
||||
return Expr(OP_ADD, self, self._make_node(other))
|
||||
|
||||
def __sub__(self, other):
|
||||
return Expr(OP_SUB, self, self._make_node(other))
|
||||
|
||||
def store_temp(self, register):
|
||||
return Expr(OP_TSTO, self, self._make_node(register))
|
||||
|
||||
def store_perm(self, register):
|
||||
return Expr(OP_PSTO, self, self._make_node(register))
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
raise NotImplementedError
|
||||
|
||||
def __str__(self):
|
||||
return '\n'.join(self.format())
|
||||
|
||||
def __repr__(self):
|
||||
return '; '.join(self.format())
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
class Expr(Node):
|
||||
def __init__(self, op, a, b):
|
||||
self.op = op
|
||||
self.a = a
|
||||
self.b = b
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
if self.op in OPERATORS:
|
||||
fmt, prio, bracket = OPERATORS[self.op]
|
||||
else:
|
||||
fmt, prio, bracket = f'{{a}} <{self.op:02x}> {{b}}', 1, True
|
||||
|
||||
ares = self.a.format(prio - 1)
|
||||
bres = self.b.format(prio - int(not bracket))
|
||||
assert len(bres) == 1, bres
|
||||
|
||||
if self.op == OP_INIT:
|
||||
ares.append(bres[0])
|
||||
return ares
|
||||
|
||||
res = fmt.format(a=ares[-1], b=bres[-1])
|
||||
if prio <= parent_priority:
|
||||
res = f'({res})'
|
||||
ares[-1] = res
|
||||
return ares
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
is_value, b_code = self.b.compile(register, shift, and_mask)
|
||||
if is_value:
|
||||
# Second arg is a simple value, do operation directly
|
||||
res = self.a.compile(register, shift, and_mask)[1]
|
||||
res += bytes((self.op,))
|
||||
res += b_code
|
||||
return False, res
|
||||
|
||||
# Calculate secord arg first and store in in a temp var
|
||||
res = b_code
|
||||
res += struct.pack('<BBBIB', OP_TSTO, 0x1a, 0x20, register, OP_INIT)
|
||||
res += self.a.compile(register + 1, shift, and_mask)[1]
|
||||
res += struct.pack('<BBBBI', self.op, 0x7d, register, 0x20, 0xffffffff)
|
||||
return False, res
|
||||
|
||||
|
||||
class Value(Node):
|
||||
def __init__(self, value):
|
||||
super().__init__()
|
||||
self.value = value
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
return [str(self.value)]
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
valueadj = (self.value >> shift) & and_mask
|
||||
return True, struct.pack('<BBI', 0x1a, 0x20, valueadj)
|
||||
|
||||
|
||||
NML_VARACT2_GLOBALVARS = {
|
||||
'current_month' : {'var': 0x02, 'start': 0, 'size': 8},
|
||||
'current_day_of_month' : {'var': 0x02, 'start': 8, 'size': 5},
|
||||
'is_leapyear' : {'var': 0x02, 'start': 15, 'size': 1},
|
||||
'current_day_of_year' : {'var': 0x02, 'start': 16, 'size': 9},
|
||||
'traffic_side' : {'var': 0x06, 'start': 4, 'size': 1},
|
||||
'animation_counter' : {'var': 0x0A, 'start': 0, 'size': 16},
|
||||
'current_callback' : {'var': 0x0C, 'start': 0, 'size': 16},
|
||||
'extra_callback_info1' : {'var': 0x10, 'start': 0, 'size': 32},
|
||||
'game_mode' : {'var': 0x12, 'start': 0, 'size': 8},
|
||||
'extra_callback_info2' : {'var': 0x18, 'start': 0, 'size': 32},
|
||||
'display_options' : {'var': 0x1B, 'start': 0, 'size': 6},
|
||||
'last_computed_result' : {'var': 0x1C, 'start': 0, 'size': 32},
|
||||
'snowline_height' : {'var': 0x20, 'start': 0, 'size': 8},
|
||||
'difficulty_level' : {'var': 0x22, 'start': 0, 'size': 8},
|
||||
'current_date' : {'var': 0x23, 'start': 0, 'size': 32},
|
||||
'current_year' : {'var': 0x24, 'start': 0, 'size': 32},
|
||||
|
||||
# TODO object vars
|
||||
'relative_x' : {'var': 0x40, 'start': 0, 'size': 8},
|
||||
'relative_y' : {'var': 0x40, 'start': 8, 'size': 8},
|
||||
'relative_pos' : {'var': 0x40, 'start': 0, 'size': 16},
|
||||
|
||||
'terrain_type' : {'var': 0x41, 'start': 0, 'size': 3},
|
||||
'tile_slope' : {'var': 0x41, 'start': 8, 'size': 5},
|
||||
|
||||
'build_date' : {'var': 0x42, 'start': 0, 'size': 32},
|
||||
|
||||
'animation_frame' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
'company_colour' : {'var': 0x43, 'start': 0, 'size': 8},
|
||||
|
||||
'owner' : {'var': 0x44, 'start': 0, 'size': 8},
|
||||
|
||||
'town_manhattan_dist' : {'var': 0x45, 'start': 0, 'size': 16},
|
||||
'town_zone' : {'var': 0x45, 'start': 16, 'size': 8},
|
||||
|
||||
'town_euclidean_dist' : {'var': 0x46, 'start': 0, 'size': 16},
|
||||
'view' : {'var': 0x48, 'start': 0, 'size': 8},
|
||||
'random_bits' : {'var': 0x5F, 'start': 8, 'size': 8},
|
||||
|
||||
# TODO object nearby vars
|
||||
'tile_height' : {'var': 0x62, 'start': 16, 'size': 8, 'param': 0},
|
||||
}
|
||||
|
||||
|
||||
class Var(Node):
|
||||
def __init__(self, name):
|
||||
super().__init__()
|
||||
self.name = name
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
return [self.name]
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
var_data = NML_VARACT2_GLOBALVARS.get(self.name)
|
||||
|
||||
if var_data is None:
|
||||
raise ValueError(f'Unknown variable `{self.name}`')
|
||||
var_mask = (1 << var_data['size']) - 1
|
||||
and_mask &= var_mask >> shift
|
||||
shift += var_data['start']
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
if 'param' in var_data:
|
||||
return True, struct.pack('<BBBI', var_data['var'], var_data['param'], 0x20 | shift, and_mask)
|
||||
else:
|
||||
return True, struct.pack('<BBI', var_data['var'], 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
class Temp(Node):
|
||||
def __init__(self, register):
|
||||
super().__init__()
|
||||
assert isinstance(register, int), type(register)
|
||||
self.register = register
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
return [f'TEMP[{self.register}]']
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
return True, struct.pack('<BBBI', 0x7d, self.register, 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
class Perm(Node):
|
||||
def __init__(self, register):
|
||||
super().__init__()
|
||||
self.register = register
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
return [f'PERM[{self.register}]']
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
return True, struct.pack('<BBI', 0x7c, 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
class Call(Node):
|
||||
def __init__(self, subroutine):
|
||||
assert 0 <= subroutine < 256, subroutine
|
||||
self.subroutine = subroutine
|
||||
|
||||
def format(self, parent_priority=0):
|
||||
return [f'call({self.subroutine})']
|
||||
|
||||
def compile(self, register, shift=0, and_mask=0xffffffff):
|
||||
assert shift < 0x20, shift
|
||||
assert and_mask <= 0xffffffff, and_mask
|
||||
return True, struct.pack('<BBBI', 0x7e, self.subroutine, 0x20 | shift, and_mask)
|
||||
|
||||
|
||||
tokens = (
|
||||
'NAME', 'NUMBER', 'NEWLINE',
|
||||
'ADD', 'SUB', 'MUL',
|
||||
'BINAND', 'BINOR', 'BINXOR', 'SHR', 'SHL',
|
||||
'ASSIGN', 'COMMA',
|
||||
'LPAREN', 'RPAREN', 'LBRACKET', 'RBRACKET',
|
||||
)
|
||||
|
||||
# Tokens
|
||||
|
||||
t_ADD = r'\+'
|
||||
t_SUB = r'-'
|
||||
t_MUL = r'\*'
|
||||
# t_DIV = r'/'
|
||||
# t_MOD = r'%'
|
||||
t_BINAND = r'\&'
|
||||
t_BINOR = r'\|'
|
||||
t_BINXOR = r'\^'
|
||||
t_SHR = r'>>'
|
||||
t_SHL = r'<<'
|
||||
t_ASSIGN = r'='
|
||||
t_COMMA = r','
|
||||
t_LPAREN = r'\('
|
||||
t_RPAREN = r'\)'
|
||||
t_LBRACKET = r'\['
|
||||
t_RBRACKET = r'\]'
|
||||
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
|
||||
|
||||
|
||||
def t_NUMBER(t):
|
||||
r'\d+'
|
||||
try:
|
||||
t.value = int(t.value)
|
||||
except ValueError:
|
||||
print("Integer value too large %d", t.value)
|
||||
t.value = 0
|
||||
return t
|
||||
|
||||
|
||||
# Ignored characters
|
||||
t_ignore = ' \t'
|
||||
|
||||
|
||||
def t_NEWLINE(t):
|
||||
r'\n+'
|
||||
t.lexer.lineno += t.value.count("\n")
|
||||
return t
|
||||
|
||||
|
||||
def t_error(t):
|
||||
print("Illegal character '%s'" % t.value[0])
|
||||
t.lexer.skip(1)
|
||||
|
||||
|
||||
# Parsing rules
|
||||
|
||||
precedence = (
|
||||
('left', 'SHR', 'SHL'),
|
||||
('left', 'BINOR'),
|
||||
('left', 'BINXOR'),
|
||||
('left', 'BINAND'),
|
||||
('left', 'ADD', 'SUB'),
|
||||
('left', 'MUL'),
|
||||
('right', 'UMINUS'),
|
||||
)
|
||||
|
||||
|
||||
def p_lines(t):
|
||||
'''lines : line
|
||||
| expression
|
||||
| lines line
|
||||
'''
|
||||
# print('LINES', t[1])
|
||||
if len(t) == 2:
|
||||
lines, line = [], t[1]
|
||||
else:
|
||||
lines, line = t[1], t[2]
|
||||
|
||||
if line is not None:
|
||||
lines.append(line)
|
||||
t[0] = lines
|
||||
|
||||
|
||||
def p_line(t):
|
||||
'''line : expression NEWLINE
|
||||
| NEWLINE
|
||||
'''
|
||||
# print('LINE', t[1], len(t))
|
||||
if len(t) == 2:
|
||||
t[0] = None
|
||||
else:
|
||||
t[0] = t[1]
|
||||
|
||||
|
||||
# def p_statement_expr(t):
|
||||
# 'statement : expression'
|
||||
# t[0] = t[1]
|
||||
|
||||
|
||||
# def p_storagge(t):
|
||||
# 'storage : NAME LBRACKET NUMBER RBRACKET'
|
||||
# storage = {
|
||||
# 'TEMP': grf.Temp,
|
||||
# 'PERM': grf.Perm,
|
||||
# }.get(t[1])
|
||||
# assert storage is not None, t[1]
|
||||
# register = int(t[3])
|
||||
|
||||
# t[0] = storage(grf.Value(register))
|
||||
|
||||
|
||||
def p_expression_binop(t):
|
||||
'''expression : expression ADD expression
|
||||
| expression SUB expression
|
||||
| expression MUL expression
|
||||
| expression BINAND expression
|
||||
| expression BINOR expression
|
||||
| expression BINXOR expression
|
||||
| expression SHL expression
|
||||
| expression SHR expression
|
||||
'''
|
||||
op = {
|
||||
'+': OP_ADD,
|
||||
'-': OP_SUB,
|
||||
'*': OP_MUL,
|
||||
'&': OP_BINAND,
|
||||
'|': OP_BINOR,
|
||||
'^': OP_BINXOR,
|
||||
'>>': OP_SHL,
|
||||
'<<': OP_SHR,
|
||||
}.get(t[2])
|
||||
|
||||
assert op is not None, t[2]
|
||||
# print(op, t[1], t[3])
|
||||
t[0] = Expr(op, t[1], t[3])
|
||||
|
||||
|
||||
# def p_storagge(t):
|
||||
# 'storage : NAME LBRACKET NUMBER RBRACKET'
|
||||
# storage = {
|
||||
# 'TEMP': grf.Temp,
|
||||
# 'PERM': grf.Perm,
|
||||
# }.get(t[1])
|
||||
# assert storage is not None, t[1]
|
||||
# register = int(t[3])
|
||||
|
||||
# t[0] = storage(grf.Value(register))
|
||||
|
||||
|
||||
def p_expression_assign(t):
|
||||
'expression : NAME LBRACKET NUMBER RBRACKET ASSIGN expression'
|
||||
assert t[1] in ('TEMP', 'PERM'), t[1]
|
||||
op = OP_TSTO if t[1] == 'TEMP' else OP_PSTO
|
||||
register = int(t[3])
|
||||
t[0] = Expr(op, t[6], Value(register))
|
||||
|
||||
|
||||
# def p_expression_uminus(t):
|
||||
# 'expression : SUB expression %prec UMINUS'
|
||||
# t[0] = -t[2]
|
||||
|
||||
|
||||
def p_expression_call1(t):
|
||||
'expression : NAME LPAREN NUMBER RPAREN'
|
||||
assert t[1] == 'call', t[1]
|
||||
t[0] = Call(int(t[3]))
|
||||
|
||||
|
||||
def p_expression_call2(t):
|
||||
'expression : NAME LPAREN expression COMMA expression RPAREN'
|
||||
op = {
|
||||
'min': OP_MIN,
|
||||
'max': OP_MAX,
|
||||
'minu': OP_MINU,
|
||||
'maxu': OP_MAXU,
|
||||
'rot': OP_ROT,
|
||||
'cmp': OP_CMP,
|
||||
'cmpu': OP_CMPU,
|
||||
}.get(t[1])
|
||||
assert op is not None, t[1]
|
||||
t[0] = Expr(op, t[3], t[5])
|
||||
|
||||
|
||||
def p_expression_group(t):
|
||||
'expression : LPAREN expression RPAREN'
|
||||
t[0] = t[2]
|
||||
|
||||
|
||||
def p_expression_storage(t):
|
||||
'expression : NAME LBRACKET NUMBER RBRACKET'
|
||||
assert t[1] in ('TEMP', 'PERM'), t[1]
|
||||
cls = Temp if t[1] == 'TEMP' else Perm
|
||||
register = int(t[3])
|
||||
t[0] = cls(register)
|
||||
|
||||
|
||||
def p_expression_number(t):
|
||||
'''expression : NUMBER
|
||||
| SUB NUMBER %prec UMINUS
|
||||
'''
|
||||
if len(t) == 2:
|
||||
t[0] = Value(int(t[1]))
|
||||
else:
|
||||
t[0] = Value(-int(t[2]))
|
||||
|
||||
|
||||
def p_expression_name(t):
|
||||
'expression : NAME'
|
||||
t[0] = Var(t[1])
|
||||
|
||||
|
||||
def p_error(t):
|
||||
# stack_state_str = ' '.join([symbol.type for symbol in parser.symstack][1:])
|
||||
|
||||
# print('Syntax error in input! Parser State:{} {} . {}'
|
||||
# .format(parser.state,
|
||||
# stack_state_str,
|
||||
# t))
|
||||
|
||||
if t is None:
|
||||
print("Unexpected syntax error")
|
||||
return
|
||||
|
||||
print(f'Syntax error at `{t.value}` line {t.lineno}')
|
||||
|
||||
|
||||
def parse_code(code):
|
||||
lexer = ply.lex.lex()
|
||||
parser = ply.yacc.yacc()
|
||||
return parser.parse(code)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
res = parse_code('''
|
||||
TEMP[128] = (cmp(tile_slope, 30) & 1) * 18
|
||||
TEMP[129] = (cmp(tile_slope, 29) & 1) * 15
|
||||
TEMP[130] = (cmp(tile_slope, 27) & 1) * 17
|
||||
TEMP[131] = (cmp(tile_slope, 23) & 1) * 16
|
||||
TEMP[132] = min(cmp(tile_slope, 0), 1)
|
||||
TEMP[134] = (min((cmp(tile_slope, 14) ^ 2), 1) & TEMP[132]) * tile_slope + TEMP[131] + TEMP[130] + TEMP[129] + TEMP[128]
|
||||
''')
|
||||
|
||||
for line in res:
|
||||
print(line.format())
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
# parsetab.py
|
||||
# This file is automatically generated. Do not edit.
|
||||
# pylint: disable=W,C,R
|
||||
_tabversion = '3.10'
|
||||
|
||||
_lr_method = 'LALR'
|
||||
|
||||
_lr_signature = 'leftSHRSHLleftBINORleftBINXORleftBINANDleftADDSUBleftMULrightUMINUSADD ASSIGN BINAND BINOR BINXOR COMMA LBRACKET LPAREN MUL NAME NEWLINE NUMBER RBRACKET RPAREN SHL SHR SUBlines : line\n | expression\n | lines line\n line : expression NEWLINE\n | NEWLINE\n expression : expression ADD expression\n | expression SUB expression\n | expression MUL expression\n | expression BINAND expression\n | expression BINOR expression\n | expression BINXOR expression\n | expression SHL expression\n | expression SHR expression\n expression : NAME LBRACKET NUMBER RBRACKET ASSIGN expressionexpression : NAME LPAREN NUMBER RPARENexpression : NAME LPAREN expression COMMA expression RPARENexpression : LPAREN expression RPARENexpression : NAME LBRACKET NUMBER RBRACKETexpression : NUMBER\n | SUB NUMBER %prec UMINUS\n expression : NAME'
|
||||
|
||||
_lr_action_items = {'NEWLINE':([0,1,2,3,4,6,7,9,10,11,20,24,25,26,27,28,29,30,31,35,36,37,41,42,],[4,4,-1,11,-5,-21,-19,-3,11,-4,-20,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,-14,-16,]),'NAME':([0,1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[6,6,-1,-2,-5,-21,-19,6,-3,-4,6,6,6,6,6,6,6,6,-20,6,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,6,6,-14,-16,]),'LPAREN':([0,1,2,3,4,6,7,8,9,11,12,13,14,15,16,17,18,19,20,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[8,8,-1,-2,-5,22,-19,8,-3,-4,8,8,8,8,8,8,8,8,-20,8,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,8,8,-14,-16,]),'NUMBER':([0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,29,30,31,35,36,37,38,39,41,42,],[7,7,-1,-2,-5,20,-21,-19,7,-3,-4,7,7,7,7,7,7,7,7,-20,32,33,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,7,7,-14,-16,]),'SUB':([0,1,2,3,4,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,26,27,28,29,30,31,33,34,35,36,37,38,39,40,41,42,],[5,5,-1,13,-5,-21,-19,5,-3,13,-4,5,5,5,5,5,5,5,5,-20,5,13,-6,-7,-8,13,13,13,13,13,-19,13,-17,-18,-15,5,5,13,13,-16,]),'$end':([1,2,3,4,6,7,9,11,20,24,25,26,27,28,29,30,31,35,36,37,41,42,],[0,-1,-2,-5,-21,-19,-3,-4,-20,-6,-7,-8,-9,-10,-11,-12,-13,-17,-18,-15,-14,-16,]),'ADD':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[12,-21,-19,12,-20,12,-6,-7,-8,12,12,12,12,12,-19,12,-17,-18,-15,12,12,-16,]),'MUL':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[14,-21,-19,14,-20,14,14,14,-8,14,14,14,14,14,-19,14,-17,-18,-15,14,14,-16,]),'BINAND':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[15,-21,-19,15,-20,15,-6,-7,-8,-9,15,15,15,15,-19,15,-17,-18,-15,15,15,-16,]),'BINOR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[16,-21,-19,16,-20,16,-6,-7,-8,-9,-10,-11,16,16,-19,16,-17,-18,-15,16,16,-16,]),'BINXOR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[17,-21,-19,17,-20,17,-6,-7,-8,-9,17,-11,17,17,-19,17,-17,-18,-15,17,17,-16,]),'SHL':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[18,-21,-19,18,-20,18,-6,-7,-8,-9,-10,-11,-12,-13,-19,18,-17,-18,-15,18,18,-16,]),'SHR':([3,6,7,10,20,23,24,25,26,27,28,29,30,31,33,34,35,36,37,40,41,42,],[19,-21,-19,19,-20,19,-6,-7,-8,-9,-10,-11,-12,-13,-19,19,-17,-18,-15,19,19,-16,]),'LBRACKET':([6,],[21,]),'RPAREN':([6,7,20,23,24,25,26,27,28,29,30,31,33,35,36,37,40,41,42,],[-21,-19,-20,35,-6,-7,-8,-9,-10,-11,-12,-13,37,-17,-18,-15,42,-14,-16,]),'COMMA':([6,7,20,24,25,26,27,28,29,30,31,33,34,35,36,37,41,42,],[-21,-19,-20,-6,-7,-8,-9,-10,-11,-12,-13,-19,38,-17,-18,-15,-14,-16,]),'RBRACKET':([32,],[36,]),'ASSIGN':([36,],[39,]),}
|
||||
|
||||
_lr_action = {}
|
||||
for _k, _v in _lr_action_items.items():
|
||||
for _x,_y in zip(_v[0],_v[1]):
|
||||
if not _x in _lr_action: _lr_action[_x] = {}
|
||||
_lr_action[_x][_k] = _y
|
||||
del _lr_action_items
|
||||
|
||||
_lr_goto_items = {'lines':([0,],[1,]),'line':([0,1,],[2,9,]),'expression':([0,1,8,12,13,14,15,16,17,18,19,22,38,39,],[3,10,23,24,25,26,27,28,29,30,31,34,40,41,]),}
|
||||
|
||||
_lr_goto = {}
|
||||
for _k, _v in _lr_goto_items.items():
|
||||
for _x, _y in zip(_v[0], _v[1]):
|
||||
if not _x in _lr_goto: _lr_goto[_x] = {}
|
||||
_lr_goto[_x][_k] = _y
|
||||
del _lr_goto_items
|
||||
_lr_productions = [
|
||||
("S' -> lines","S'",1,None,None,None),
|
||||
('lines -> line','lines',1,'p_lines','parser.py',334),
|
||||
('lines -> expression','lines',1,'p_lines','parser.py',335),
|
||||
('lines -> lines line','lines',2,'p_lines','parser.py',336),
|
||||
('line -> expression NEWLINE','line',2,'p_line','parser.py',350),
|
||||
('line -> NEWLINE','line',1,'p_line','parser.py',351),
|
||||
('expression -> expression ADD expression','expression',3,'p_expression_binop','parser.py',378),
|
||||
('expression -> expression SUB expression','expression',3,'p_expression_binop','parser.py',379),
|
||||
('expression -> expression MUL expression','expression',3,'p_expression_binop','parser.py',380),
|
||||
('expression -> expression BINAND expression','expression',3,'p_expression_binop','parser.py',381),
|
||||
('expression -> expression BINOR expression','expression',3,'p_expression_binop','parser.py',382),
|
||||
('expression -> expression BINXOR expression','expression',3,'p_expression_binop','parser.py',383),
|
||||
('expression -> expression SHL expression','expression',3,'p_expression_binop','parser.py',384),
|
||||
('expression -> expression SHR expression','expression',3,'p_expression_binop','parser.py',385),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET ASSIGN expression','expression',6,'p_expression_assign','parser.py',416),
|
||||
('expression -> NAME LPAREN NUMBER RPAREN','expression',4,'p_expression_call1','parser.py',429),
|
||||
('expression -> NAME LPAREN expression COMMA expression RPAREN','expression',6,'p_expression_call2','parser.py',435),
|
||||
('expression -> LPAREN expression RPAREN','expression',3,'p_expression_group','parser.py',450),
|
||||
('expression -> NAME LBRACKET NUMBER RBRACKET','expression',4,'p_expression_storage','parser.py',455),
|
||||
('expression -> NUMBER','expression',1,'p_expression_number','parser.py',463),
|
||||
('expression -> SUB NUMBER','expression',2,'p_expression_number','parser.py',464),
|
||||
('expression -> NAME','expression',1,'p_expression_name','parser.py',472),
|
||||
]
|
||||