From 495f2e3cc07b1cb1958d1c904f2ac83e625a6c3c Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:06:59 +0200 Subject: [PATCH 01/97] Add some typing to common functions --- arch/zx48k/backend/__common.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/backend/__common.py b/arch/zx48k/backend/__common.py index 5ab300caf..21dc518e1 100644 --- a/arch/zx48k/backend/__common.py +++ b/arch/zx48k/backend/__common.py @@ -41,13 +41,13 @@ def init(): TMP_LABELS.clear() -def log2(x): +def log2(x) -> float: """ Returns log2(x) """ return math.log(x) / __LN2 -def is_2n(x): +def is_2n(x) -> bool: """ Returns true if x is an exact power of 2 """ @@ -55,7 +55,7 @@ def is_2n(x): return l == int(l) -def tmp_label(): +def tmp_label() -> str: global LABEL_COUNTER global TMP_LABELS @@ -66,7 +66,7 @@ def tmp_label(): return result -def tmp_temp(): +def tmp_temp() -> str: global TMP_COUNTER for i in range(TMP_COUNTER): From 62c604a025f34ea13a483f8b376054b3645c2654 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 00:48:03 +0200 Subject: [PATCH 02/97] Add TranslatorInstVisitor This subclass NodeVisitor adding functions for each IC instruction. --- arch/zx48k/translatorinstvisitor.py | 236 ++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 arch/zx48k/translatorinstvisitor.py diff --git a/arch/zx48k/translatorinstvisitor.py b/arch/zx48k/translatorinstvisitor.py new file mode 100644 index 000000000..911a5d599 --- /dev/null +++ b/arch/zx48k/translatorinstvisitor.py @@ -0,0 +1,236 @@ +# -*- coding: utf-8 -*- + +from api.constants import TYPE +import symbols + +from ast_ import NodeVisitor +from .backend import Quad, MEMORY +from api.debug import __DEBUG__ + + +class TranslatorInstVisitor(NodeVisitor): + @staticmethod + def emit(*args): + """ Convert the given args to a Quad (3 address code) instruction + """ + quad = Quad(*args) + __DEBUG__('EMIT ' + str(quad)) + MEMORY.append(quad) + + @staticmethod + def TSUFFIX(type_): + assert isinstance(type_, symbols.TYPE) or TYPE.is_valid(type_) + + _TSUFFIX = {TYPE.byte_: 'i8', TYPE.ubyte: 'u8', + TYPE.integer: 'i16', TYPE.uinteger: 'u16', + TYPE.long_: 'i32', TYPE.ulong: 'u32', + TYPE.fixed: 'f16', TYPE.float_: 'f', + TYPE.string: 'str' + } + + if isinstance(type_, symbols.TYPEREF): + type_ = type_.final + assert isinstance(type_, symbols.BASICTYPE) + + if isinstance(type_, symbols.BASICTYPE): + return _TSUFFIX[type_.type_] + + return _TSUFFIX[type_] + + def ic_aaddr(self, t1, t2): + return self.emit('aaddr', t1, t2) + + def ic_abs(self, type_, t1, t2): + return self.emit('abs' + self.TSUFFIX(type_), t1, t2) + + def ic_add(self, type_, t1, t2, t3): + return self.emit('add' + self.TSUFFIX(type_), t1, t2, t3) + + def ic_aload(self, type_, t1, mangle: str): + return self.emit('aload' + self.TSUFFIX(type_), t1, mangle) + + def ic_and(self, type_): + return self.emit('and' + self.TSUFFIX(type_)) + + def ic_astore(self, type_, addr: str, t): + return self.emit('astore' + self.TSUFFIX(type_), addr, t) + + def ic_band(self, type_): + return self.emit('band' + self.TSUFFIX(type_)) + + def ic_bnot(self, type_, t1, t2): + return self.emit('bnot' + self.TSUFFIX(type_), t1, t2) + + def ic_bor(self, type_): + return self.emit('bor' + self.TSUFFIX(type_)) + + def ic_bxor(self, type_): + return self.emit('bxor' + self.TSUFFIX(type_)) + + def ic_call(self, label: str, num: int): + return self.emit('call', label, num) + + def ic_cast(self, t1, type1, type2, t2): + self.emit('cast', t1, self.TSUFFIX(type1), self.TSUFFIX(type2), t2) + + def ic_data(self, type_, data: list): + return self.emit('data', self.TSUFFIX(type_), data) + + def ic_deflabel(self, label: str, t): + return self.emit('deflabel', label, t) + + def ic_div(self, type_): + return self.emit('div' + self.TSUFFIX(type_)) + + def ic_end(self, t): + return self.emit('end', t) + + def ic_enter(self, arg): + return self.emit('enter', arg) + + def ic_eq(self, type_, t, t1, t2): + return self.emit('eq' + self.TSUFFIX(type_), t, t1, t2) + + def ic_exchg(self): + return self.emit('exchg') + + def ic_fparam(self, type_, t): + return self.emit('fparam' + self.TSUFFIX(type_), t) + + def ic_fpload(self, type_, t, offset): + return self.emit('fpload' + self.TSUFFIX(type_), t, offset) + + def ic_ge(self, type_, t, t1, t2): + return self.emit('ge' + self.TSUFFIX(type_), t, t1, t2) + + def ic_gt(self, type_, t, t1, t2): + return self.emit('gt' + self.TSUFFIX(type_), t, t1, t2) + + def ic_in(self, t): + return self.emit('in', t) + + def ic_inline(self, asm_code: str, t): + return self.emit('inline', asm_code, t) + + def ic_jgezero(self, type_, t, label: str): + return self.emit('jgezero' + self.TSUFFIX(type_), t, label) + + def ic_jnzero(self, type_, t, label: str): + return self.emit('jnzero' + self.TSUFFIX(type_), t, label) + + def ic_jump(self, label: str): + return self.emit('jump', label) + + def ic_jzero(self, type_, t, label: str): + return self.emit('jzero' + self.TSUFFIX(type_), t, label) + + def ic_label(self, label: str): + return self.emit('label', label) + + def ic_larrd(self, offset, arg1, size, arg2): + return self.emit('larrd', offset, arg1, size, arg2) + + def ic_le(self, type_, t, t1, t2): + return self.emit('le' + self.TSUFFIX(type_), t, t1, t2) + + def ic_leave(self, convention: str): + return self.emit('leave', convention) + + def ic_lenstr(self, t1, t2): + return self.emit('lenstr', t1, t2) + + def ic_load(self, type_, t1, t2): + return self.emit('load' + self.TSUFFIX(type_), t1, t2) + + def ic_lt(self, type_, t, t1, t2): + return self.emit('lt' + self.TSUFFIX(type_), t, t1, t2) + + def ic_lvard(self, offset, default_value: list): + return self.emit('lvard', offset, default_value) + + def ic_lvarx(self, type_, offset, default_value: list): + self.emit('lvarx', offset, self.TSUFFIX(type_), default_value) + + def ic_memcopy(self, t1, t2, t3): + return self.emit('memcopy', t1, t2, t3) + + def ic_mod(self, type_): + return self.emit('mod' + self.TSUFFIX(type_)) + + def ic_mul(self, type_): + return self.emit('mul' + self.TSUFFIX(type_)) + + def ic_ne(self, type_, t, t1, t2): + return self.emit('ne' + self.TSUFFIX(type_), t, t1, t2) + + def ic_neg(self, type_, t1, t2): + return self.emit('neg' + self.TSUFFIX(type_), t1, t2) + + def ic_nop(self): + return self.emit('nop') + + def ic_not(self, type_, t1, t2): + return self.emit('not' + self.TSUFFIX(type_), t1, t2) + + def ic_or(self, type_): + return self.emit('or' + self.TSUFFIX(type_)) + + def ic_org(self, type_): + return self.emit('org' + self.TSUFFIX(type_)) + + def ic_out(self, t1, t2): + return self.emit('out', t1, t2) + + def ic_paaddr(self, t1, t2): + return self.emit('paaddr', t1, t2) + + def ic_paddr(self, t1, t2): + return self.emit('paddr', t1, t2) + + def ic_paload(self, type_, t, offset: int): + return self.emit('paload' + self.TSUFFIX(type_), t, offset) + + def ic_param(self, type_, t): + return self.emit('param' + self.TSUFFIX(type_), t) + + def ic_pastore(self, type_, offset, t): + return self.emit('pastore' + self.TSUFFIX(type_), offset, t) + + def ic_pload(self, type_, t1, t2): + return self.emit('pload' + self.TSUFFIX(type_), t1, t2) + + def ic_pow(self, type_): + return self.emit('pow' + self.TSUFFIX(type_)) + + def ic_pstore(self, type_, offset, t): + return self.emit('pstore' + self.TSUFFIX(type_), offset, t) + + def ic_ret(self, type_, t, addr): + return self.emit('ret' + self.TSUFFIX(type_), t, addr) + + def ic_return(self, addr): + return self.emit('ret', addr) + + def ic_shl(self, type_): + return self.emit('shl' + self.TSUFFIX(type_)) + + def ic_shr(self, type_): + return self.emit('shr' + self.TSUFFIX(type_)) + + def ic_store(self, type_, t1, t2): + return self.emit('store' + self.TSUFFIX(type_), t1, t2) + + def ic_sub(self, type_): + return self.emit('sub' + self.TSUFFIX(type_)) + + def ic_var(self, name: str, size_): + return self.emit('var', name, size_) + + def ic_vard(self, name: str, data: list): + return self.emit('vard', name, data) + + def ic_varx(self, name: str, type_, default_value: list): + return self.emit('varx', name, self.TSUFFIX(type_), default_value) + + def ic_xor(self, type_): + return self.emit('xor' + self.TSUFFIX(type_)) From 6ccc85af5acb812db3f7296623dab686c6a932a8 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 00:48:22 +0200 Subject: [PATCH 03/97] Decouples TranslatorVisitor to its own file Move this base class to its own file for better refactoring --- arch/zx48k/translator.py | 271 +------------------------------- arch/zx48k/translatorvisitor.py | 257 ++++++++++++++++++++++++++++++ 2 files changed, 258 insertions(+), 270 deletions(-) create mode 100644 arch/zx48k/translatorvisitor.py diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 2dad6c53e..8ba79ac5c 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1,7 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from collections import OrderedDict from collections import namedtuple from api.constants import TYPE @@ -16,23 +15,18 @@ from api.debug import __DEBUG__ from api.errmsg import syntax_error -from api.errmsg import syntax_error_not_constant -from api.errmsg import syntax_error_cant_convert_to_type from api.config import OPTIONS from api.global_ import optemps from api.errors import InvalidLoopError from api.errors import InvalidOperatorError -from api.errors import InvalidCONSTexpr from api.errors import InvalidBuiltinFunctionError -from symbols.symbol_ import Symbol from . import backend -from .backend import Quad, MEMORY -from ast_ import NodeVisitor from .backend.__float import _float import symbols from symbols.type_ import Type +from .translatorvisitor import TranslatorVisitor import arch.zx48k # TODO: put this in global @@ -43,272 +37,9 @@ JumpTable = namedtuple('JumpTable', ('label', 'addresses')) -class TranslatorVisitor(NodeVisitor): - """ This visitor just adds the emit() method. - """ - # ------------------------------------------------ - # A list of tokens that belongs to temporary - # ATTR setting - # ------------------------------------------------ - ATTR = ('INK', 'PAPER', 'BRIGHT', 'FLASH', 'OVER', 'INVERSE', 'BOLD', 'ITALIC') - ATTR_TMP = tuple(x + '_TMP' for x in ATTR) - - # Local flags - HAS_ATTR = False - - # Previous Token - PREV_TOKEN = None - - # Current Token - CURR_TOKEN = None - - LOOPS = [] # Defined LOOPS - STRING_LABELS = OrderedDict() - JUMP_TABLES = [] - - # Type code used in DATA - DATA_TYPES = { - 'str': 1, - 'i8': 2, - 'u8': 3, - 'i16': 4, - 'u16': 5, - 'i32': 6, - 'u32': 7, - 'f16': 8, - 'f': 9 - } - - @classmethod - def reset(cls): - cls.LOOPS = [] # Defined LOOPS - cls.STRING_LABELS = OrderedDict() - cls.JUMP_TABLES = [] - - def add_string_label(self, str_): - """ Maps ("folds") the given string, returning an unique label ID. - This allows several constant labels to be initialized to the same address - thus saving memory space. - :param str_: the string to map - :return: the unique label ID - """ - if self.STRING_LABELS.get(str_, None) is None: - self.STRING_LABELS[str_] = backend.tmp_label() - - return self.STRING_LABELS[str_] - - @property - def O_LEVEL(self): - return OPTIONS.optimization.value - - @staticmethod - def TYPE(type_): - """ Converts a backend type (from api.constants) - to a SymbolTYPE object (taken from the SYMBOL_TABLE). - If type_ is already a SymbolTYPE object, nothing - is done. - """ - if isinstance(type_, symbols.TYPE): - return type_ - - assert TYPE.is_valid(type_) - return gl.SYMBOL_TABLE.basic_types[type_] - - @staticmethod - def TSUFFIX(type_): - assert isinstance(type_, symbols.TYPE) or TYPE.is_valid(type_) - - _TSUFFIX = {TYPE.byte_: 'i8', TYPE.ubyte: 'u8', - TYPE.integer: 'i16', TYPE.uinteger: 'u16', - TYPE.long_: 'i32', TYPE.ulong: 'u32', - TYPE.fixed: 'f16', TYPE.float_: 'f', - TYPE.string: 'str' - } - - if isinstance(type_, symbols.TYPEREF): - type_ = type_.final - assert isinstance(type_, symbols.BASICTYPE) - - if isinstance(type_, symbols.BASICTYPE): - return _TSUFFIX[type_.type_] - - return _TSUFFIX[type_] - - @staticmethod - def emit(*args): - """ Convert the given args to a Quad (3 address code) instruction - """ - quad = Quad(*args) - __DEBUG__('EMIT ' + str(quad)) - MEMORY.append(quad) - - @staticmethod - def dumpMemory(MEMORY): - """ Returns a sequence of Quads - """ - for x in MEMORY: - yield str(x) - - # Generic Visitor methods - def visit_BLOCK(self, node): - __DEBUG__('BLOCK', 2) - for child in node.children: - yield child - - # Visits any temporal attribute - def visit_ATTR_TMP(self, node): - yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', node.token, 0) # Procedure call. Discard return - ifile = node.token.lower() - ifile = ifile[:ifile.index('_')] - backend.REQUIRES.add(ifile + '.asm') - - # This function must be called before emit_strings - def emit_data_blocks(self): - if not gl.DATA_IS_USED: - return # nothing to do - - for label_, datas in gl.DATAS: - self.emit('label', label_) - for d in datas: - if isinstance(d, symbols.FUNCDECL): - type_ = '%02Xh' % (self.DATA_TYPES[self.TSUFFIX(d.type_)] | 0x80) - self.emit('data', self.TSUFFIX(TYPE.byte_), [type_]) - self.emit('data', self.TSUFFIX(gl.PTR_TYPE), [d.mangled]) - continue - - self.emit('data', self.TSUFFIX(TYPE.byte_), [self.DATA_TYPES[self.TSUFFIX(d.value.type_)]]) - if d.value.type_ == self.TYPE(TYPE.string): - lbl = self.add_string_label(d.value.value) - self.emit('data', self.TSUFFIX(api.global_.PTR_TYPE), [lbl]) - elif d.value.type_ == self.TYPE(TYPE.fixed): # Convert to bytes - bytes_ = 0xFFFFFFFF & int(d.value.value * 2 ** 16) - self.emit('data', self.TSUFFIX(TYPE.uinteger), - ['0x%04X' % (bytes_ & 0xFFFF), '0x%04X' % (bytes_ >> 16)]) - else: - self.emit('data', self.TSUFFIX(d.value.type_), [self.traverse_const(d.value)]) - - if not gl.DATAS: # The above loop was not executed, because there's no data - self.emit('label', '__DATA__0') - - self.emit('vard', '__DATA__END', ['00']) - - def emit_strings(self): - for str_, label_ in self.STRING_LABELS.items(): - l = '%04X' % (len(str_) & 0xFFFF) # TODO: Universalize for any arch - self.emit('vard', label_, [l] + ['%02X' % ord(x) for x in str_]) - - def emit_jump_tables(self): - for table_ in self.JUMP_TABLES: - self.emit('vard', table_.label, [str(len(table_.addresses))] + - ['##' + x.mangled for x in table_.addresses]) - - def _visit(self, node): - self.norm_attr() - if isinstance(node, Symbol): - __DEBUG__('Visiting {}'.format(node.token), 1) - if node.token in self.ATTR_TMP: - return self.visit_ATTR_TMP(node) - - return NodeVisitor._visit(self, node) - - def norm_attr(self): - """ Normalize attr state - """ - if not self.HAS_ATTR: - return - - self.HAS_ATTR = False - self.emit('call', 'COPY_ATTR', 0) - backend.REQUIRES.add('copy_attr.asm') - - @staticmethod - def traverse_const(node): - """ Traverses a constant and returns an string - with the arithmetic expression - """ - if node.token == 'NUMBER': - return node.t - - if node.token == 'UNARY': - mid = node.operator - if mid == 'MINUS': - result = ' -' + Translator.traverse_const(node.operand) - elif mid == 'ADDRESS': - if node.operand.scope == SCOPE.global_ or node.operand.token in ('LABEL', 'FUNCTION'): - result = Translator.traverse_const(node.operand) - else: - syntax_error_not_constant(node.operand.lineno) - return - else: - raise InvalidOperatorError(mid) - return result - - if node.token == 'BINARY': - mid = node.operator - if mid == 'PLUS': - mid = '+' - elif mid == 'MINUS': - mid = '-' - elif mid == 'MUL': - mid = '*' - elif mid == 'DIV': - mid = '/' - elif mid == 'MOD': - mid = '%' - elif mid == 'POW': - mid = '^' - elif mid == 'SHL': - mid = '>>' - elif mid == 'SHR': - mid = '<<' - else: - raise InvalidOperatorError(mid) - - return '(%s) %s (%s)' % (Translator.traverse_const(node.left), mid, Translator.traverse_const(node.right)) - - if node.token == 'TYPECAST': - if node.type_ in (Type.byte_, Type.ubyte): - return '(' + Translator.traverse_const(node.operand) + ') & 0xFF' - if node.type_ in (Type.integer, Type.uinteger): - return '(' + Translator.traverse_const(node.operand) + ') & 0xFFFF' - if node.type_ in (Type.long_, Type.ulong): - return '(' + Translator.traverse_const(node.operand) + ') & 0xFFFFFFFF' - if node.type_ == Type.fixed: - return '((' + Translator.traverse_const(node.operand) + ') & 0xFFFF) << 16' - syntax_error_cant_convert_to_type(node.lineno, str(node.operand), node.type_) - return - - if node.token == 'VARARRAY': - return node.data_label - - if node.token in ('VAR', 'LABEL', 'FUNCTION'): - # TODO: Check what happens with local vars and params - return node.t - - if node.token == 'CONST': - return Translator.traverse_const(node.expr) - - if node.token == 'ARRAYACCESS': - return '({} + {})'.format(node.entry.data_label, node.offset) - - raise InvalidCONSTexpr(node) - - @staticmethod - def check_attr(node, n): - """ Check if ATTR has to be normalized - after this instruction has been translated - to intermediate code. - """ - if len(node.children) > n: - return node.children[n] - - class Translator(TranslatorVisitor): """ ZX Spectrum translator """ - def visit_NOP(self, node): pass # nothing to do diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py new file mode 100644 index 000000000..ee10a610f --- /dev/null +++ b/arch/zx48k/translatorvisitor.py @@ -0,0 +1,257 @@ +# -*- coding: utf-8 -*- + +from collections import OrderedDict +from api.errmsg import syntax_error_not_constant +from api.errmsg import syntax_error_cant_convert_to_type +from api.debug import __DEBUG__ + +from api.errors import InvalidCONSTexpr +from api.config import OPTIONS +from api.constants import TYPE +from api.constants import SCOPE +import api.global_ as gl + +from symbols.symbol_ import Symbol +from symbols.type_ import Type + +from . import backend +import symbols + +from api.errors import InvalidOperatorError + +from .translatorinstvisitor import TranslatorInstVisitor + + +class TranslatorVisitor(TranslatorInstVisitor): + """ This visitor just adds the emit() method. + """ + # ------------------------------------------------ + # A list of tokens that belongs to temporary + # ATTR setting + # ------------------------------------------------ + ATTR = ('INK', 'PAPER', 'BRIGHT', 'FLASH', 'OVER', 'INVERSE', 'BOLD', 'ITALIC') + ATTR_TMP = tuple(x + '_TMP' for x in ATTR) + + # Local flags + HAS_ATTR = False + + # Previous Token + PREV_TOKEN = None + + # Current Token + CURR_TOKEN = None + + LOOPS = [] # Defined LOOPS + STRING_LABELS = OrderedDict() + JUMP_TABLES = [] + + # Type code used in DATA + DATA_TYPES = { + 'str': 1, + 'i8': 2, + 'u8': 3, + 'i16': 4, + 'u16': 5, + 'i32': 6, + 'u32': 7, + 'f16': 8, + 'f': 9 + } + + @classmethod + def reset(cls): + cls.LOOPS = [] # Defined LOOPS + cls.STRING_LABELS = OrderedDict() + cls.JUMP_TABLES = [] + + def add_string_label(self, str_): + """ Maps ("folds") the given string, returning an unique label ID. + This allows several constant labels to be initialized to the same address + thus saving memory space. + :param str_: the string to map + :return: the unique label ID + """ + if self.STRING_LABELS.get(str_, None) is None: + self.STRING_LABELS[str_] = backend.tmp_label() + + return self.STRING_LABELS[str_] + + @property + def O_LEVEL(self): + return OPTIONS.optimization.value + + @staticmethod + def TYPE(type_): + """ Converts a backend type (from api.constants) + to a SymbolTYPE object (taken from the SYMBOL_TABLE). + If type_ is already a SymbolTYPE object, nothing + is done. + """ + if isinstance(type_, symbols.TYPE): + return type_ + + assert TYPE.is_valid(type_) + return gl.SYMBOL_TABLE.basic_types[type_] + + @staticmethod + def dumpMemory(MEMORY): + """ Returns a sequence of Quads + """ + for x in MEMORY: + yield str(x) + + # Generic Visitor methods + def visit_BLOCK(self, node): + __DEBUG__('BLOCK', 2) + for child in node.children: + yield child + + # Visits any temporal attribute + def visit_ATTR_TMP(self, node): + yield node.children[0] + self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.emit('call', node.token, 0) # Procedure call. Discard return + ifile = node.token.lower() + ifile = ifile[:ifile.index('_')] + backend.REQUIRES.add(ifile + '.asm') + + # This function must be called before emit_strings + def emit_data_blocks(self): + if not gl.DATA_IS_USED: + return # nothing to do + + for label_, datas in gl.DATAS: + self.emit('label', label_) + for d in datas: + if isinstance(d, symbols.FUNCDECL): + type_ = '%02Xh' % (self.DATA_TYPES[self.TSUFFIX(d.type_)] | 0x80) + self.emit('data', self.TSUFFIX(TYPE.byte_), [type_]) + self.emit('data', self.TSUFFIX(gl.PTR_TYPE), [d.mangled]) + continue + + self.emit('data', self.TSUFFIX(TYPE.byte_), [self.DATA_TYPES[self.TSUFFIX(d.value.type_)]]) + if d.value.type_ == self.TYPE(TYPE.string): + lbl = self.add_string_label(d.value.value) + self.emit('data', self.TSUFFIX(gl.PTR_TYPE), [lbl]) + elif d.value.type_ == self.TYPE(TYPE.fixed): # Convert to bytes + bytes_ = 0xFFFFFFFF & int(d.value.value * 2 ** 16) + self.emit('data', self.TSUFFIX(TYPE.uinteger), + ['0x%04X' % (bytes_ & 0xFFFF), '0x%04X' % (bytes_ >> 16)]) + else: + self.emit('data', self.TSUFFIX(d.value.type_), [self.traverse_const(d.value)]) + + if not gl.DATAS: # The above loop was not executed, because there's no data + self.emit('label', '__DATA__0') + + self.emit('vard', '__DATA__END', ['00']) + + def emit_strings(self): + for str_, label_ in self.STRING_LABELS.items(): + l = '%04X' % (len(str_) & 0xFFFF) # TODO: Universalize for any arch + self.emit('vard', label_, [l] + ['%02X' % ord(x) for x in str_]) + + def emit_jump_tables(self): + for table_ in self.JUMP_TABLES: + self.emit('vard', table_.label, [str(len(table_.addresses))] + + ['##' + x.mangled for x in table_.addresses]) + + def _visit(self, node): + self.norm_attr() + if isinstance(node, Symbol): + __DEBUG__('Visiting {}'.format(node.token), 1) + if node.token in self.ATTR_TMP: + return self.visit_ATTR_TMP(node) + + return TranslatorInstVisitor._visit(self, node) + + def norm_attr(self): + """ Normalize attr state + """ + if not self.HAS_ATTR: + return + + self.HAS_ATTR = False + self.emit('call', 'COPY_ATTR', 0) + backend.REQUIRES.add('copy_attr.asm') + + @staticmethod + def traverse_const(node): + """ Traverses a constant and returns an string + with the arithmetic expression + """ + if node.token == 'NUMBER': + return node.t + + if node.token == 'UNARY': + mid = node.operator + if mid == 'MINUS': + result = ' -' + TranslatorVisitor.traverse_const(node.operand) + elif mid == 'ADDRESS': + if node.operand.scope == SCOPE.global_ or node.operand.token in ('LABEL', 'FUNCTION'): + result = TranslatorVisitor.traverse_const(node.operand) + else: + syntax_error_not_constant(node.operand.lineno) + return + else: + raise InvalidOperatorError(mid) + return result + + if node.token == 'BINARY': + mid = node.operator + if mid == 'PLUS': + mid = '+' + elif mid == 'MINUS': + mid = '-' + elif mid == 'MUL': + mid = '*' + elif mid == 'DIV': + mid = '/' + elif mid == 'MOD': + mid = '%' + elif mid == 'POW': + mid = '^' + elif mid == 'SHL': + mid = '>>' + elif mid == 'SHR': + mid = '<<' + else: + raise InvalidOperatorError(mid) + + return '(%s) %s (%s)' % (TranslatorVisitor.traverse_const(node.left), mid, + TranslatorVisitor.traverse_const(node.right)) + + if node.token == 'TYPECAST': + if node.type_ in (Type.byte_, Type.ubyte): + return '(' + TranslatorVisitor.traverse_const(node.operand) + ') & 0xFF' + if node.type_ in (Type.integer, Type.uinteger): + return '(' + TranslatorVisitor.traverse_const(node.operand) + ') & 0xFFFF' + if node.type_ in (Type.long_, Type.ulong): + return '(' + TranslatorVisitor.traverse_const(node.operand) + ') & 0xFFFFFFFF' + if node.type_ == Type.fixed: + return '((' + TranslatorVisitor.traverse_const(node.operand) + ') & 0xFFFF) << 16' + syntax_error_cant_convert_to_type(node.lineno, str(node.operand), node.type_) + return + + if node.token == 'VARARRAY': + return node.data_label + + if node.token in ('VAR', 'LABEL', 'FUNCTION'): + # TODO: Check what happens with local vars and params + return node.t + + if node.token == 'CONST': + return TranslatorVisitor.traverse_const(node.expr) + + if node.token == 'ARRAYACCESS': + return '({} + {})'.format(node.entry.data_label, node.offset) + + raise InvalidCONSTexpr(node) + + @staticmethod + def check_attr(node, n): + """ Check if ATTR has to be normalized + after this instruction has been translated + to intermediate code. + """ + if len(node.children) > n: + return node.children[n] From 4b58729bb6d2c381273b35256ceabde07589d5d4 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 01:09:01 +0200 Subject: [PATCH 04/97] Refact: use self.ic_call in TranslatorVisitor --- arch/zx48k/translatorvisitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py index ee10a610f..20fb91632 100644 --- a/arch/zx48k/translatorvisitor.py +++ b/arch/zx48k/translatorvisitor.py @@ -110,7 +110,7 @@ def visit_BLOCK(self, node): def visit_ATTR_TMP(self, node): yield node.children[0] self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', node.token, 0) # Procedure call. Discard return + self.ic_call(node.token, 0) # Procedure call. Discard return ifile = node.token.lower() ifile = ifile[:ifile.index('_')] backend.REQUIRES.add(ifile + '.asm') @@ -171,7 +171,7 @@ def norm_attr(self): return self.HAS_ATTR = False - self.emit('call', 'COPY_ATTR', 0) + self.ic_call('COPY_ATTR', 0) backend.REQUIRES.add('copy_attr.asm') @staticmethod From 15abf1bf8418f58282ab8b2d28f2a1746fc5577a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 01:17:37 +0200 Subject: [PATCH 05/97] Refact: use self.ic_data in TranslatorVisitor --- arch/zx48k/translatorvisitor.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py index 20fb91632..ce5116ccd 100644 --- a/arch/zx48k/translatorvisitor.py +++ b/arch/zx48k/translatorvisitor.py @@ -125,20 +125,19 @@ def emit_data_blocks(self): for d in datas: if isinstance(d, symbols.FUNCDECL): type_ = '%02Xh' % (self.DATA_TYPES[self.TSUFFIX(d.type_)] | 0x80) - self.emit('data', self.TSUFFIX(TYPE.byte_), [type_]) - self.emit('data', self.TSUFFIX(gl.PTR_TYPE), [d.mangled]) + self.ic_data(TYPE.byte_, [type_]) + self.ic_data(gl.PTR_TYPE, [d.mangled]) continue - self.emit('data', self.TSUFFIX(TYPE.byte_), [self.DATA_TYPES[self.TSUFFIX(d.value.type_)]]) + self.ic_data(TYPE.byte_, [self.DATA_TYPES[self.TSUFFIX(d.value.type_)]]) if d.value.type_ == self.TYPE(TYPE.string): lbl = self.add_string_label(d.value.value) - self.emit('data', self.TSUFFIX(gl.PTR_TYPE), [lbl]) + self.ic_data(gl.PTR_TYPE, [lbl]) elif d.value.type_ == self.TYPE(TYPE.fixed): # Convert to bytes bytes_ = 0xFFFFFFFF & int(d.value.value * 2 ** 16) - self.emit('data', self.TSUFFIX(TYPE.uinteger), - ['0x%04X' % (bytes_ & 0xFFFF), '0x%04X' % (bytes_ >> 16)]) + self.ic_data(TYPE.uinteger, ['0x%04X' % (bytes_ & 0xFFFF), '0x%04X' % (bytes_ >> 16)]) else: - self.emit('data', self.TSUFFIX(d.value.type_), [self.traverse_const(d.value)]) + self.ic_data(d.value.type_, [self.traverse_const(d.value)]) if not gl.DATAS: # The above loop was not executed, because there's no data self.emit('label', '__DATA__0') From 9ef23804be65266ee8c22bc2da9fae81af9e5fc0 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 01:24:16 +0200 Subject: [PATCH 06/97] Refact: use self.ic_label in TranslatorVisitor --- arch/zx48k/translatorvisitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py index ce5116ccd..e519f5022 100644 --- a/arch/zx48k/translatorvisitor.py +++ b/arch/zx48k/translatorvisitor.py @@ -121,7 +121,7 @@ def emit_data_blocks(self): return # nothing to do for label_, datas in gl.DATAS: - self.emit('label', label_) + self.ic_label(label_) for d in datas: if isinstance(d, symbols.FUNCDECL): type_ = '%02Xh' % (self.DATA_TYPES[self.TSUFFIX(d.type_)] | 0x80) @@ -140,7 +140,7 @@ def emit_data_blocks(self): self.ic_data(d.value.type_, [self.traverse_const(d.value)]) if not gl.DATAS: # The above loop was not executed, because there's no data - self.emit('label', '__DATA__0') + self.ic_label('__DATA__0') self.emit('vard', '__DATA__END', ['00']) From 72d511eeca8cf5b7b5f55cd24a0505ccb7605af3 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 01:28:54 +0200 Subject: [PATCH 07/97] Refact: use self.ic_vard in TranslatorVisitor --- arch/zx48k/translatorvisitor.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py index e519f5022..445647c44 100644 --- a/arch/zx48k/translatorvisitor.py +++ b/arch/zx48k/translatorvisitor.py @@ -142,17 +142,16 @@ def emit_data_blocks(self): if not gl.DATAS: # The above loop was not executed, because there's no data self.ic_label('__DATA__0') - self.emit('vard', '__DATA__END', ['00']) + self.ic_vard('__DATA__END', ['00']) def emit_strings(self): for str_, label_ in self.STRING_LABELS.items(): l = '%04X' % (len(str_) & 0xFFFF) # TODO: Universalize for any arch - self.emit('vard', label_, [l] + ['%02X' % ord(x) for x in str_]) + self.ic_vard(label_, [l] + ['%02X' % ord(x) for x in str_]) def emit_jump_tables(self): for table_ in self.JUMP_TABLES: - self.emit('vard', table_.label, [str(len(table_.addresses))] + - ['##' + x.mangled for x in table_.addresses]) + self.ic_vard(table_.label, [str(len(table_.addresses))] + ['##' + x.mangled for x in table_.addresses]) def _visit(self, node): self.norm_attr() From 82c7b418249aec122d84af874a393a6c7fa1a179 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 01:33:29 +0200 Subject: [PATCH 08/97] Refact: use self.ic_fparam in TranslatorVisitor --- arch/zx48k/translatorvisitor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translatorvisitor.py b/arch/zx48k/translatorvisitor.py index 445647c44..d3c0f6253 100644 --- a/arch/zx48k/translatorvisitor.py +++ b/arch/zx48k/translatorvisitor.py @@ -109,7 +109,7 @@ def visit_BLOCK(self, node): # Visits any temporal attribute def visit_ATTR_TMP(self, node): yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.ic_fparam(node.children[0].type_, node.children[0].t) self.ic_call(node.token, 0) # Procedure call. Discard return ifile = node.token.lower() ifile = ifile[:ifile.index('_')] From a76efbb39bb409789f68ba777ea5c0e1dd06864e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:39:25 +0200 Subject: [PATCH 09/97] Refactorize CLS visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8ba79ac5c..98d44f70e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -44,7 +44,7 @@ def visit_NOP(self, node): pass # nothing to do def visit_CLS(self, node): - self.emit('call', 'CLS', 0) + self.ic_call('CLS', 0) backend.REQUIRES.add('cls.asm') def visit_NUMBER(self, node): From 4235b5bb11015fa8083db5dc6fa3c87283f001fd Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:39:39 +0200 Subject: [PATCH 10/97] Refactorize END visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 98d44f70e..5ffa76121 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -59,7 +59,7 @@ def visit_STRING(self, node): def visit_END(self, node): yield node.children[0] __DEBUG__('END') - self.emit('end', node.children[0].t) + self.ic_end(node.children[0].t) def visit_ERROR(self, node): # Raises an error From 4373723f4fe35828327ca0c75314e70f3c8b64cd Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:39:56 +0200 Subject: [PATCH 11/97] Refactorize ERROR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 5ffa76121..c64b937cb 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -64,8 +64,8 @@ def visit_END(self, node): def visit_ERROR(self, node): # Raises an error yield node.children[0] - self.emit('fparamu8', node.children[0].t) - self.emit('call', '__ERROR', 0) + self.ic_fparam(TYPE.ubyte, node.children[0].t) + self.ic_call('__ERROR', 0) backend.REQUIRES.add('error.asm') def visit_STOP(self, node): From 1ae9f8e7490d376c27812d2a0a45116aa34f2675 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:40:10 +0200 Subject: [PATCH 12/97] Refactorize STOP visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index c64b937cb..095d1dc11 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -72,9 +72,9 @@ def visit_STOP(self, node): """ Returns to BASIC with an error code """ yield node.children[0] - self.emit('fparamu8', node.children[0].t) - self.emit('call', '__STOP', 0) - self.emit('end', 0) + self.ic_fparam(TYPE.ubyte, node.children[0].t) + self.ic_call('__STOP', 0) + self.ic_end(0) backend.REQUIRES.add('error.asm') def visit_LET(self, node): From 50df0063caa6dba2d65807449543248ae462f145 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:44:34 +0200 Subject: [PATCH 13/97] Refactorize POKE visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 095d1dc11..90b413ca3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -91,9 +91,9 @@ def visit_POKE(self, node): yield ch1 if ch0.token == 'VAR' and ch0.class_ != CLASS.const and ch0.scope == SCOPE.global_: - self.emit('store' + self.TSUFFIX(ch1.type_), '*' + str(ch0.t), ch1.t) + self.ic_store(ch1.type_, '*' + str(ch0.t), ch1.t) else: - self.emit('store' + self.TSUFFIX(ch1.type_), ch0.t, ch1.t) + self.ic_store(ch1.type_, str(ch0.t), ch1.t) def visit_RANDOMIZE(self, node): yield node.children[0] From 44e94c6dcdf257bec6289830ff7292bf9dc34de3 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:46:27 +0200 Subject: [PATCH 14/97] Refactorize RANDOMIZE visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 90b413ca3..c30cfa839 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -97,8 +97,8 @@ def visit_POKE(self, node): def visit_RANDOMIZE(self, node): yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', 'RANDOMIZE', 0) + self.ic_fparam(node.children[0].type_, node.children[0].t) + self.ic_call('RANDOMIZE', 0) backend.REQUIRES.add('random.asm') def visit_LABEL(self, node): From 6422cb901fba50b5ec9d728a3f7c8efd8b3a1907 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 10:48:49 +0200 Subject: [PATCH 15/97] Refactorize LABEL visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index c30cfa839..19e470eae 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -102,9 +102,9 @@ def visit_RANDOMIZE(self, node): backend.REQUIRES.add('random.asm') def visit_LABEL(self, node): - self.emit('label', node.mangled) + self.ic_label(node.mangled) for tmp in node.aliased_by: - self.emit('label', tmp.mangled) + self.ic_label(tmp.mangled) def visit_VAR(self, node): __DEBUG__('{}: VAR {}:{} Scope: {} Class: {}'.format(node.lineno, node.name, node.type_, From 73913c363625304e85b336c437f73b449a0cd16c Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 11:06:22 +0200 Subject: [PATCH 16/97] Refactorize VAR visit --- arch/zx48k/translator.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 19e470eae..7305e88e5 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -117,20 +117,16 @@ def visit_VAR(self, node): if node.class_ in (CLASS.label, CLASS.const): return - suffix = self.TSUFFIX(node.type_) p = '*' if node.byref else '' # Indirection prefix - alias = node.alias - if scope == SCOPE.global_: - self.emit('load' + suffix, node.t, node.mangled) - elif scope == SCOPE.parameter: - self.emit('pload' + suffix, node.t, p + str(node.offset)) + if scope == SCOPE.parameter: + self.ic_pload(node.type_, node.t, p + str(node.offset)) elif scope == SCOPE.local: offset = node.offset - if alias is not None and alias.class_ == CLASS.array: - offset -= 1 + 2 * alias.count + if node.alias is not None and node.alias.class_ == CLASS.array: + offset -= 1 + 2 * node.alias.count # TODO this is actually NOT implemented - self.emit('pload' + suffix, node.t, p + str(-offset)) + self.ic_pload(node.type_, node.t, p + str(-offset)) def visit_CONST(self, node): node.t = '#' + (self.traverse_const(node) or '') From 05d7b17ab5d39d6eff04c1941696eb7aea2a5dd0 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 21:04:00 +0200 Subject: [PATCH 17/97] Refactorize TYPECAST visit --- arch/zx48k/translator.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 7305e88e5..06c16803d 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -170,8 +170,7 @@ def visit_TYPECAST(self, node): yield node.operand assert node.operand.type_.is_basic assert node.type_.is_basic - self.emit('cast', node.t, self.TSUFFIX(node.operand.type_.type_), - self.TSUFFIX(node.type_.type_), node.operand.t) + self.ic_cast(node.t, node.operand.type_, node.type_, node.operand.t) def visit_FUNCDECL(self, node): # Delay emission of functions until the end of the main code From 15149dd11ff31f0d34dc58868b968aef9de5a136 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 22:18:05 +0200 Subject: [PATCH 18/97] Refactorize CALL visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 06c16803d..3bff84570 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -180,11 +180,11 @@ def visit_CALL(self, node): yield node.args # arglist if node.entry.convention == CONVENTION.fastcall: if len(node.args) > 0: # At least 1 parameter - self.emit('fparam' + self.TSUFFIX(node.args[0].type_), optemps.new_t()) + self.ic_fparam(node.args[0].type_, optemps.new_t()) - self.emit('call', node.entry.mangled, 0) # Procedure call. 0 = discard return + self.ic_call(node.entry.mangled, 0) # Procedure call. 0 = discard return if node.entry.kind == KIND.function and node.entry.type_ == self.TYPE(TYPE.string): - self.emit('call', '__MEM_FREE', 0) # Discard string return value if the called function has any + self.ic_call('__MEM_FREE', 0) # Discard string return value if the called function has any backend.REQUIRES.add('free.asm') def visit_ARGLIST(self, node): From 60b127bea0e9b2a9d5ffa864de4614f146bc2339 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 22:22:59 +0200 Subject: [PATCH 19/97] Refactorize ARGLIST visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 3bff84570..b1cd95b64 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -194,7 +194,7 @@ def visit_ARGLIST(self, node): if isinstance(node.parent, symbols.ARRAYACCESS) and OPTIONS.arrayCheck.value: upper = node.parent.entry.bounds[i].upper lower = node.parent.entry.bounds[i].lower - self.emit('paramu16', upper - lower) + self.ic_param(gl.PTR_TYPE, upper - lower) def visit_ARGUMENT(self, node): if not node.byref: From 3814e79b913e3172d186385064056ced94eea715 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Thu, 18 Jul 2019 22:37:07 +0200 Subject: [PATCH 20/97] Refactorize ARGUMENT visit --- arch/zx48k/translator.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index b1cd95b64..2dd4f3fdf 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -198,18 +198,17 @@ def visit_ARGLIST(self, node): def visit_ARGUMENT(self, node): if not node.byref: - suffix = self.TSUFFIX(node.type_) if node.value.token in ('VAR', 'PARAMDECL') and \ node.type_.is_dynamic and node.value.t[0] == '$': # Duplicate it in the heap assert (node.value.scope in (SCOPE.local, SCOPE.parameter)) if node.value.scope == SCOPE.local: - self.emit('pload' + suffix, node.t, str(-node.value.offset)) + self.ic_pload(node.type_, node.t, str(-node.value.offset)) else: # PARAMETER - self.emit('pload' + suffix, node.t, str(node.value.offset)) + self.ic_pload(node.type_, node.t, str(node.value.offset)) else: yield node.value - self.emit('param' + suffix, node.t) + self.ic_param(node.type_, node.t) else: scope = node.value.scope if node.t[0] == '_': @@ -218,16 +217,16 @@ def visit_ARGUMENT(self, node): t = node.t if scope == SCOPE.global_: - self.emit('loadu16', t, '#' + node.mangled) + self.ic_load(TYPE.uinteger, t, '#' + node.mangled) elif scope == SCOPE.parameter: # A function has used a parameter as an argument to another function call if not node.value.byref: # It's like a local variable - self.emit('paddr', node.value.offset, t) + self.ic_paddr(node.value.offset, t) else: - self.emit('ploadu16', t, str(node.value.offset)) + self.ic_pload(TYPE.uinteger, t, str(node.value.offset)) elif scope == SCOPE.local: - self.emit('paddr', -node.value.offset, t) + self.ic_paddr(-node.value.offset, t) - self.emit('paramu16', t) + self.ic_param(TYPE.uinteger, t) def visit_ARRAYLOAD(self, node): scope = node.entry.scope From c64a13d7706682c06dc7142aa18d3f5c4093de7d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Fri, 19 Jul 2019 00:07:42 +0200 Subject: [PATCH 21/97] Refactorize ARRAYLOAD visit --- arch/zx48k/translator.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 2dd4f3fdf..ca406173e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -235,25 +235,24 @@ def visit_ARRAYLOAD(self, node): yield node.args if scope == SCOPE.global_: - self.emit('aload' + self.TSUFFIX(node.type_), node.entry.t, node.entry.mangled) + self.ic_aload(node.type_, node.entry.t, node.entry.mangled) elif scope == SCOPE.parameter: - self.emit('paload' + self.TSUFFIX(node.type_), node.t, node.entry.offset) + self.ic_paload(node.type_, node.t, node.entry.offset) elif scope == SCOPE.local: - self.emit('paload' + self.TSUFFIX(node.type_), node.t, -node.entry.offset) + self.ic_paload(node.type_, node.t, -node.entry.offset) else: offset = node.offset if scope == SCOPE.global_: - self.emit('load' + self.TSUFFIX(node.type_), node.entry.t, '%s + %i' % (node.entry.t, offset)) + self.ic_load(node.type_, node.entry.t, '%s + %i' % (node.entry.t, offset)) elif scope == SCOPE.parameter: - self.emit('pload' + self.TSUFFIX(node.type_), node.t, node.entry.offset - offset) + self.ic_pload(node.type_, node.t, node.entry.offset - offset) elif scope == SCOPE.local: t1 = optemps.new_t() t2 = optemps.new_t() t3 = optemps.new_t() - self.emit('pload' + self.TSUFFIX(gl.PTR_TYPE), t1, - -(node.entry.offset - self.TYPE(gl.PTR_TYPE).size)) - self.emit('add' + self.TSUFFIX(gl.PTR_TYPE), t2, t1, node.offset) - self.emit('load' + self.TSUFFIX(node.type_), t3, '*$%s' % t2) + self.ic_pload(gl.PTR_TYPE, t1, -(node.entry.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_add(gl.PTR_TYPE, t2, t1, node.offset) + self.ic_load(node.type_, t3, '*$%s' % t2) def visit_ARRAYCOPY(self, node): tr = node.children[0] From b389fe7cabf6d938fbc0161d53891054224aaac1 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Fri, 19 Jul 2019 00:23:30 +0200 Subject: [PATCH 22/97] Refactorize ARRAYCOPY visit --- arch/zx48k/translator.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index ca406173e..1e83b15c1 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -261,10 +261,10 @@ def visit_ARRAYCOPY(self, node): t1 = "#%s" % tr.data_label elif scope == SCOPE.parameter: t1 = optemps.new_t() - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t1, '%i' % (tr.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t1, '%i' % (tr.offset - self.TYPE(gl.PTR_TYPE).size)) elif scope == SCOPE.local: t1 = optemps.new_t() - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t1, '%i' % -(tr.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t1, '%i' % -(tr.offset - self.TYPE(gl.PTR_TYPE).size)) tr = node.children[1] scope = tr.scope @@ -272,18 +272,18 @@ def visit_ARRAYCOPY(self, node): t2 = "#%s" % tr.data_label elif scope == SCOPE.parameter: t2 = optemps.new_t() - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, '%i' % (tr.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t2, '%i' % (tr.offset - self.TYPE(gl.PTR_TYPE).size)) elif scope == SCOPE.local: t2 = optemps.new_t() - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, '%i' % -(tr.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(tr.offset - self.TYPE(gl.PTR_TYPE).size)) t = optemps.new_t() if tr.type_ != Type.string: - self.emit('load%s' % self.TSUFFIX(gl.PTR_TYPE), t, '%i' % tr.size) - self.emit('memcopy', t1, t2, t) + self.ic_load(gl.PTR_TYPE, t, '%i' % tr.size) + self.ic_memcopy(t1, t2, t) else: - self.emit('load%s' % self.TSUFFIX(gl.PTR_TYPE), '%i' % tr.count) - self.emit('call', 'STR_ARRAYCOPY', 0) + self.ic_load(gl.PTR_TYPE, '%i' % tr.count) + self.ic_call('STR_ARRAYCOPY', 0) backend.REQUIRES.add('strarraycpy.asm') def visit_LETARRAY(self, node): From 0ecdd1077e3984e6ed5d5d39b1d903246369e5f8 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Fri, 19 Jul 2019 00:33:00 +0200 Subject: [PATCH 23/97] Refactorize LETARRAY visit --- arch/zx48k/translator.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 1e83b15c1..8269555b7 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -293,25 +293,24 @@ def visit_LETARRAY(self, node): yield node.children[1] # Right expression arr = node.children[0] # Array access scope = arr.scope - suf = self.TSUFFIX(arr.type_) if arr.offset is None: yield arr if scope == SCOPE.global_: - self.emit('astore' + suf, arr.entry.mangled, node.children[1].t) + self.ic_astore(arr.type_, arr.entry.mangled, node.children[1].t) elif scope == SCOPE.parameter: - self.emit('pastore' + suf, arr.entry.offset, node.children[1].t) + self.ic_pastore(arr.type_, arr.entry.offset, node.children[1].t) elif scope == SCOPE.local: - self.emit('pastore' + suf, -arr.entry.offset, node.children[1].t) + self.ic_pastore(arr.type_, -arr.entry.offset, node.children[1].t) else: name = arr.entry.data_label if scope == SCOPE.global_: - self.emit('store' + suf, '%s + %i' % (name, arr.offset), node.children[1].t) + self.ic_store(arr.type_, '%s + %i' % (name, arr.offset), node.children[1].t) elif scope == SCOPE.parameter: - self.emit('pstore' + suf, arr.entry.offset - arr.offset, node.children[1].t) + self.ic_pstore(arr.type_, arr.entry.offset - arr.offset, node.children[1].t) elif scope == SCOPE.local: - self.emit('pstore' + suf, -(arr.entry.offset - arr.offset), node.children[1].t) + self.ic_pstore(arr.type_, -(arr.entry.offset - arr.offset), node.children[1].t) def visit_LETSUBSTR(self, node): yield node.children[3] From 802341472a03cba2f8e54ba9a57689576716f17b Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Fri, 19 Jul 2019 00:37:31 +0200 Subject: [PATCH 24/97] Refactorize LETSUBSTR visit --- arch/zx48k/translator.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8269555b7..fd2d445c8 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -314,21 +314,20 @@ def visit_LETARRAY(self, node): def visit_LETSUBSTR(self, node): yield node.children[3] - self.emit('paramstr', node.children[3].t) + self.ic_param(TYPE.string, node.children[3].t) if node.children[3].token != 'STRING' and (node.children[3].token != 'VAR' or node.children[3].mangled[0] != '_'): - self.emit('paramu8', 1) # If the argument is not a variable, it must be freed + self.ic_param(TYPE.ubyte, 1) # If the argument is not a variable, it must be freed else: - self.emit('paramu8', 0) + self.ic_param(TYPE.ubyte, 0) yield node.children[1] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[1].t) + self.ic_param(gl.PTR_TYPE, node.children[1].t) yield node.children[2] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[2].t) - - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.children[0].t) - self.emit('call', '__LETSUBSTR', 0) + self.ic_param(gl.PTR_TYPE, node.children[2].t) + self.ic_fparam(gl.PTR_TYPE, node.children[0].t) + self.ic_call('__LETSUBSTR', 0) backend.REQUIRES.add('letsubstr.asm') def visit_LETARRAYSUBSTR(self, node): From e9c12160e4da9f1b8d267e152721fb417cd9e807 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Fri, 19 Jul 2019 00:50:34 +0200 Subject: [PATCH 25/97] Refactorize LETARRAYSUBSTR visit --- arch/zx48k/translator.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index fd2d445c8..9d647b10d 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -336,43 +336,42 @@ def visit_LETARRAYSUBSTR(self, node): expr = node.children[3] # right expression yield expr - self.emit('paramstr', expr.t) + self.ic_param(TYPE.string, expr.t) if expr.token != 'STRING' and (expr.token != 'VAR' or expr.mangled[0] != '_'): - self.emit('paramu8', 1) # If the argument is not a variable, it must be freed + self.ic_param(TYPE.ubyte, 1) # If the argument is not a variable, it must be freed else: - self.emit('paramu8', 0) + self.ic_param(TYPE.ubyte, 0) yield node.children[1] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[1].t) + self.ic_param(gl.PTR_TYPE, node.children[1].t) yield node.children[2] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[2].t) + self.ic_param(gl.PTR_TYPE, node.children[2].t) node_ = node.children[0] scope = node_.scope entry = node_.entry - suffix = self.TSUFFIX(gl.PTR_TYPE) # Address of an array element. if node_.offset is None: yield node_ if scope == SCOPE.global_: - self.emit('aload' + suffix, node_.t, entry.mangled) - elif scope == 'parameter': - self.emit('paloadstr' + suffix, node_.t, entry.offset) - elif scope == 'local': - self.emit('paloadstr' + suffix, node_.t, -entry.offset) + self.ic_aload(gl.PTR_TYPE, node_.t, entry.mangled) + elif scope == SCOPE.parameter: # TODO: These 2 are never used!?? + self.ic_paload(gl.PTR_TYPE, node_.t, entry.offset) + elif scope == SCOPE.local: + self.ic_paload(gl.PTR_TYPE, node_.t, -entry.offset) else: offset = node_.offset if scope == SCOPE.global_: - self.emit('load' + suffix, entry.t, '%s + %i' % (entry.mangled, offset)) + self.ic_load(gl.PTR_TYPE, entry.t, '%s + %i' % (entry.mangled, offset)) elif scope == SCOPE.parameter: - self.emit('pload' + suffix, node_.t, entry.offset - offset) + self.ic_pload(gl.PTR_TYPE, node_.t, entry.offset - offset) elif scope == SCOPE.local: - self.emit('pload' + suffix, node_.t, -(entry.offset - offset)) + self.ic_pload(gl.PTR_TYPE, node_.t, -(entry.offset - offset)) - self.emit('fparam' + suffix, node.children[0].t) - self.emit('call', '__LETSUBSTR', 0) + self.ic_fparam(gl.PTR_TYPE, node.children[0].t) + self.ic_call('__LETSUBSTR', 0) backend.REQUIRES.add('letsubstr.asm') def visit_ARRAYACCESS(self, node): From 710ae6daef0d135e6a969838282e031050c3da7d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:07:24 +0200 Subject: [PATCH 26/97] Refactorize STRSLICE visit --- arch/zx48k/translator.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9d647b10d..6f768c206 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -381,22 +381,22 @@ def visit_STRSLICE(self, node): yield node.string if node.string.token == 'STRING' or \ node.string.token == 'VAR' and node.string.scope == SCOPE.global_: - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.string.t) + self.ic_param(gl.PTR_TYPE, node.string.t) # Now emit the slicing indexes yield node.lower - self.emit('param' + self.TSUFFIX(node.lower.type_), node.lower.t) + self.ic_param(node.lower.type_, node.lower.t) yield node.upper - self.emit('param' + self.TSUFFIX(node.upper.type_), node.upper.t) + self.ic_param(node.upper.type_, node.upper.t) if (node.string.token in ('VAR', 'PARAMDECL') and node.string.mangled[0] == '_' or node.string.token == 'STRING'): - self.emit('fparamu8', 0) + self.ic_fparam(TYPE.ubyte, 0) else: - self.emit('fparamu8', 1) # If the argument is not a variable, it must be freed + self.ic_fparam(TYPE.ubyte, 1) # If the argument is not a variable, it must be freed - self.emit('call', '__STRSLICE', self.TYPE(gl.PTR_TYPE).size) + self.ic_call('__STRSLICE', self.TYPE(gl.PTR_TYPE).size) backend.REQUIRES.add('strslice.asm') def visit_FUNCCALL(self, node): From 536694bb4f92a377f03c5dbcf9fef47bed2822dc Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:09:59 +0200 Subject: [PATCH 27/97] Refactorize FUNCCALL visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 6f768c206..66a288e27 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -404,9 +404,9 @@ def visit_FUNCCALL(self, node): if node.entry.convention == CONVENTION.fastcall: if len(node.args) > 0: # At least 1 - self.emit('fparam' + self.TSUFFIX(node.args[0].type_), optemps.new_t()) + self.ic_fparam(node.args[0].type_, optemps.new_t()) - self.emit('call', node.entry.mangled, node.entry.size) + self.ic_call(node.entry.mangled, node.entry.size) def visit_RESTORE(self, node): if not gl.DATA_IS_USED: From a74a400676db442cdb6714318f71952e91525429 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:16:01 +0200 Subject: [PATCH 28/97] Refactorize RESTORE visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 66a288e27..f7ae3552e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -412,8 +412,8 @@ def visit_RESTORE(self, node): if not gl.DATA_IS_USED: return # If no READ is used, ignore all DATA related statements lbl = gl.DATA_LABELS[node.args[0].name] - self.emit('fparam' + self.TSUFFIX(node.args[0].type_), '#' + lbl) - self.emit('call', '__RESTORE', 0) + self.ic_fparam(node.args[0].type_, '#' + lbl) + self.ic_call('__RESTORE', 0) backend.REQUIRES.add('read_restore.asm') def visit_READ(self, node): From 2fe7f36f40db0b3c1c8f78b9e78994ec9d336e7a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:25:46 +0200 Subject: [PATCH 29/97] Refactorize READ visit --- arch/zx48k/translator.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f7ae3552e..4dbd87ded 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -417,33 +417,31 @@ def visit_RESTORE(self, node): backend.REQUIRES.add('read_restore.asm') def visit_READ(self, node): - self.emit('fparamu8', '#' + str(self.DATA_TYPES[self.TSUFFIX(node.args[0].type_)])) - self.emit('call', '__READ', node.args[0].type_.size) + self.ic_fparam(TYPE.ubyte, '#' + str(self.DATA_TYPES[self.TSUFFIX(node.args[0].type_)])) + self.ic_call('__READ', node.args[0].type_.size) if isinstance(node.args[0], symbols.ARRAYACCESS): arr = node.args[0] t = api.global_.optemps.new_t() scope = arr.scope - suf = self.TSUFFIX(arr.type_) if arr.offset is None: yield arr if scope == SCOPE.global_: - self.emit('astore' + suf, arr.entry.mangled, t) + self.ic_astore(arr.type_, arr.entry.mangled, t) elif scope == SCOPE.parameter: - self.emit('pastore' + suf, arr.entry.offset, t) + self.ic_pastore(arr.type_, arr.entry.offset, t) elif scope == SCOPE.local: - self.emit('pastore' + suf, -arr.entry.offset, t) + self.ic_pastore(arr.type_, -arr.entry.offset, t) else: name = arr.entry.mangled if scope == SCOPE.global_: - self.emit('store' + suf, '%s + %i' % (name, arr.offset), t) + self.ic_store(arr.type_, '%s + %i' % (name, arr.offset), t) elif scope == SCOPE.parameter: - self.emit('pstore' + suf, arr.entry.offset - arr.offset, t) + self.ic_pstore(arr.type_, arr.entry.offset - arr.offset, t) elif scope == SCOPE.local: - self.emit('pstore' + suf, -(arr.entry.offset - arr.offset), t) - + self.ic_pstore(arr.type_, -(arr.entry.offset - arr.offset), t) else: self.emit_var_assign(node.args[0], t=api.global_.optemps.new_t()) backend.REQUIRES.add('read_restore.asm') From 0a67f30c2d1e5c2e9c388d260a60a9fd25d29f52 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:29:10 +0200 Subject: [PATCH 30/97] Refactorize DO LOOP visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 4dbd87ded..0d3dae7ac 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -455,12 +455,12 @@ def visit_DO_LOOP(self, node): end_loop = backend.tmp_label() self.LOOPS.append(('DO', end_loop, loop_label)) # Saves which labels to jump upon EXIT or CONTINUE - self.emit('label', loop_label) + self.ic_label(loop_label) if node.children: yield node.children[0] - self.emit('jump', loop_label) - self.emit('label', end_loop) + self.ic_jump(loop_label) + self.ic_label(end_loop) self.LOOPS.pop() # del loop_label, end_loop From bf571c0b0182354d1b9d44e40ecaf426f6c93b61 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:33:52 +0200 Subject: [PATCH 31/97] Refactorize DO WHILE visit --- arch/zx48k/translator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 0d3dae7ac..5b2d2b517 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -473,18 +473,18 @@ def visit_DO_WHILE(self, node): continue_loop = backend.tmp_label() if node.token == 'WHILE_DO': - self.emit('jump', continue_loop) + self.ic_jump(continue_loop) - self.emit('label', loop_label) + self.ic_label(loop_label) self.LOOPS.append(('DO', end_loop, continue_loop)) # Saves which labels to jump upon EXIT or CONTINUE if len(node.children) > 1: yield node.children[1] - self.emit('label', continue_loop) + self.ic_label(continue_loop) yield node.children[0] - self.emit('jnzero' + self.TSUFFIX(node.children[0].type_), node.children[0].t, loop_label) - self.emit('label', end_loop) + self.ic_jnzero(node.children[0].type_, node.children[0].t, loop_label) + self.ic_label(end_loop) self.LOOPS.pop() # del loop_label, end_loop, continue_loop From 842a9ef71665406d9cc1c3686ce957ec78b70947 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:34:57 +0200 Subject: [PATCH 32/97] Refactorize EXIT DO visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 5b2d2b517..ff9663079 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -489,7 +489,7 @@ def visit_DO_WHILE(self, node): # del loop_label, end_loop, continue_loop def visit_EXIT_DO(self, node): - self.emit('jump', self.loop_exit_label('DO')) + self.ic_jump(self.loop_exit_label('DO')) def visit_EXIT_WHILE(self, node): self.emit('jump', self.loop_exit_label('WHILE')) From 0dbe0a59608598aae8af55ff759a6167076fabaa Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:35:17 +0200 Subject: [PATCH 33/97] Refactorize EXIT WHILE visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index ff9663079..47a587f94 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -492,7 +492,7 @@ def visit_EXIT_DO(self, node): self.ic_jump(self.loop_exit_label('DO')) def visit_EXIT_WHILE(self, node): - self.emit('jump', self.loop_exit_label('WHILE')) + self.ic_jump(self.loop_exit_label('WHILE')) def visit_EXIT_FOR(self, node): self.emit('jump', self.loop_exit_label('FOR')) From 27d6bf5498a60aca2758c53eeeaa7760342cd6c8 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:35:50 +0200 Subject: [PATCH 34/97] Refactorize EXIT FOR visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 47a587f94..5a39b779e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -495,7 +495,7 @@ def visit_EXIT_WHILE(self, node): self.ic_jump(self.loop_exit_label('WHILE')) def visit_EXIT_FOR(self, node): - self.emit('jump', self.loop_exit_label('FOR')) + self.ic_jump(self.loop_exit_label('FOR')) def visit_CONTINUE_DO(self, node): self.emit('jump', self.loop_cont_label('DO')) From 24a29c05f9977697a16f02e667430414bbfb849c Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 21 Jul 2019 20:37:08 +0200 Subject: [PATCH 35/97] Refactorize CONTINUE DO visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 5a39b779e..fba82205d 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -498,7 +498,7 @@ def visit_EXIT_FOR(self, node): self.ic_jump(self.loop_exit_label('FOR')) def visit_CONTINUE_DO(self, node): - self.emit('jump', self.loop_cont_label('DO')) + self.ic_jump(self.loop_cont_label('DO')) def visit_CONTINUE_WHILE(self, node): self.emit('jump', self.loop_cont_label('WHILE')) From 468a0f81820af7b89e869d6e131e875306e7221a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Mon, 22 Jul 2019 00:21:55 +0200 Subject: [PATCH 36/97] Refactorize CONTINUE WHILE visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index fba82205d..dee42bc05 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -501,7 +501,7 @@ def visit_CONTINUE_DO(self, node): self.ic_jump(self.loop_cont_label('DO')) def visit_CONTINUE_WHILE(self, node): - self.emit('jump', self.loop_cont_label('WHILE')) + self.ic_jump(self.loop_cont_label('WHILE')) def visit_CONTINUE_FOR(self, node): self.emit('jump', self.loop_cont_label('FOR')) From ecc92628c8b3b5f58a72f3ae96a96ea11b6ffbd5 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Mon, 22 Jul 2019 00:23:05 +0200 Subject: [PATCH 37/97] Refactorize CONTINUE FOR visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index dee42bc05..0f6604d21 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -504,7 +504,7 @@ def visit_CONTINUE_WHILE(self, node): self.ic_jump(self.loop_cont_label('WHILE')) def visit_CONTINUE_FOR(self, node): - self.emit('jump', self.loop_cont_label('FOR')) + self.ic_jump(self.loop_cont_label('FOR')) def visit_FOR(self, node): loop_label_start = backend.tmp_label() From 970569ae40e4c1039c92babfaf9377ec9d5d3b2a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:07:35 +0200 Subject: [PATCH 38/97] Refactorize FOR visit --- arch/zx48k/translator.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 0f6604d21..f381c49aa 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -512,30 +512,30 @@ def visit_FOR(self, node): end_loop = backend.tmp_label() loop_body = backend.tmp_label() loop_continue = backend.tmp_label() - suffix = self.TSUFFIX(node.children[0].type_) + type_ = node.children[0].type_ self.LOOPS.append(('FOR', end_loop, loop_continue)) # Saves which label to jump upon EXIT FOR and CONTINUE FOR yield node.children[1] # Gets starting value (lower limit) self.emit_let_left_part(node) # Stores it in the iterator variable - self.emit('jump', loop_label_start) + self.ic_jump(loop_label_start) # FOR body statements - self.emit('label', loop_body) + self.ic_label(loop_body) yield node.children[4] # Jump here to continue next iteration - self.emit('label', loop_continue) + self.ic_label(loop_continue) # VAR = VAR + STEP yield node.children[0] # Iterator Var yield node.children[3] # Step t = optemps.new_t() - self.emit('add' + suffix, t, node.children[0].t, node.children[3].t) + self.ic_add(type_, t, node.children[0].t, node.children[3].t) self.emit_let_left_part(node, t) # Loop starts here - self.emit('label', loop_label_start) + self.ic_label(loop_label_start) # Emmit condition if check.is_number(node.children[3]) or check.is_unsigned(node.children[3].type_): @@ -543,27 +543,27 @@ def visit_FOR(self, node): else: direct = False yield node.children[3] # Step - self.emit('jgezero' + suffix, node.children[3].t, loop_label_gt) + self.ic_jgezero(type_, node.children[3].t, loop_label_gt) if not direct or node.children[3].value < 0: # Here for negative steps # Compares if var < limit2 yield node.children[0] # Value of var yield node.children[2] # Value of limit2 - self.emit('lt' + suffix, node.t, node.children[0].t, node.children[2].t) - self.emit('jzerou8', node.t, loop_body) + self.ic_lt(type_, node.t, node.children[0].t, node.children[2].t) + self.ic_jzero(TYPE.ubyte, node.t, loop_body) if not direct: - self.emit('jump', end_loop) - self.emit('label', loop_label_gt) + self.ic_jump(end_loop) + self.ic_label(loop_label_gt) if not direct or node.children[3].value >= 0: # Here for positive steps # Compares if var > limit2 yield node.children[0] # Value of var yield node.children[2] # Value of limit2 - self.emit('gt' + suffix, node.t, node.children[0].t, node.children[2].t) - self.emit('jzerou8', node.t, loop_body) + self.ic_gt(type_, node.t, node.children[0].t, node.children[2].t) + self.ic_jzero(TYPE.ubyte, node.t, loop_body) - self.emit('label', end_loop) + self.ic_label(end_loop) self.LOOPS.pop() def visit_GOTO(self, node): From 284c56fb123cd8f90057e5a02d319ed0fd4f14cc Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:08:43 +0200 Subject: [PATCH 39/97] Refactorize GOTO visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f381c49aa..1f003b270 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -567,7 +567,7 @@ def visit_FOR(self, node): self.LOOPS.pop() def visit_GOTO(self, node): - self.emit('jump', node.children[0].mangled) + self.ic_jump(node.children[0].mangled) def visit_GOSUB(self, node): self.emit('call', node.children[0].mangled, 0) From 12e1b425371a4b1dc93d0ccb0e3295e01355b7b2 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:08:53 +0200 Subject: [PATCH 40/97] Refactorize GOSUB visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 1f003b270..018012fef 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -570,7 +570,7 @@ def visit_GOTO(self, node): self.ic_jump(node.children[0].mangled) def visit_GOSUB(self, node): - self.emit('call', node.children[0].mangled, 0) + self.ic_call(node.children[0].mangled, 0) def visit_ON_GOTO(self, node): table_label = backend.tmp_label() From 1351b27f802f3868ef8037e4460094d734bb9d58 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:11:09 +0200 Subject: [PATCH 41/97] Refactorize ONGOTO visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 018012fef..64c19e4a5 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -574,10 +574,10 @@ def visit_GOSUB(self, node): def visit_ON_GOTO(self, node): table_label = backend.tmp_label() - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), '#' + table_label) + self.ic_param(gl.PTR_TYPE, '#' + table_label) yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', '__ON_GOTO', 0) + self.ic_fparam(node.children[0].type_, node.children[0].t) + self.ic_call('__ON_GOTO', 0) self.JUMP_TABLES.append(JumpTable(table_label, node.children[1:])) backend.REQUIRES.add('ongoto.asm') From 83b3bcf592635bf309186093e5fa8bf9ec53757e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:13:28 +0200 Subject: [PATCH 42/97] Refactorize ONGOSUB visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 64c19e4a5..e59731ed8 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -583,10 +583,10 @@ def visit_ON_GOTO(self, node): def visit_ON_GOSUB(self, node): table_label = backend.tmp_label() - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), '#' + table_label) + self.ic_param(gl.PTR_TYPE, '#' + table_label) yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', '__ON_GOSUB', 0) + self.ic_fparam(node.children[0].type_, node.children[0].t) + self.ic_call('__ON_GOSUB', 0) self.JUMP_TABLES.append(JumpTable(table_label, node.children[1:])) backend.REQUIRES.add('ongoto.asm') From 7e113b1d55a80643f2cb2f83ac47c1dbb7930b68 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:27:00 +0200 Subject: [PATCH 43/97] Refactorize CHKBREAK visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index e59731ed8..436984f02 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -592,9 +592,9 @@ def visit_ON_GOSUB(self, node): def visit_CHKBREAK(self, node): if self.PREV_TOKEN != node.token: - self.emit('inline', 'push hl', node.children[0].t) - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.children[0].t) - self.emit('call', 'CHECK_BREAK', 0) + self.ic_inline('push hl', node.children[0].t) + self.ic_fparam(gl.PTR_TYPE, node.children[0].t) + self.ic_call('CHECK_BREAK', 0) backend.REQUIRES.add('break.asm') def visit_IF(self, node): From 90ffa0467699230eb3c23d48136867f0499612fa Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:36:11 +0200 Subject: [PATCH 44/97] Refactorize IF visit --- arch/zx48k/translator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 436984f02..9855c0613 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -604,18 +604,18 @@ def visit_IF(self, node): if_label_endif = backend.tmp_label() if len(node.children) == 3: # Has else? - self.emit('jzero' + self.TSUFFIX(node.children[0].type_), node.children[0].t, if_label_else) + self.ic_jzero(node.children[0].type_, node.children[0].t, if_label_else) else: - self.emit('jzero' + self.TSUFFIX(node.children[0].type_), node.children[0].t, if_label_endif) + self.ic_jzero(node.children[0].type_, node.children[0].t, if_label_endif) yield node.children[1] # THEN... if len(node.children) == 3: # Has else? - self.emit('jump', if_label_endif) - self.emit('label', if_label_else) + self.ic_jump(if_label_endif) + self.ic_label(if_label_else) yield node.children[2] - self.emit('label', if_label_endif) + self.ic_label(if_label_endif) def visit_RETURN(self, node): if len(node.children) == 2: # Something to return? From bd29f4597b52a5c344366ebd0eb6ccb41f62b71a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Tue, 23 Jul 2019 00:44:10 +0200 Subject: [PATCH 45/97] Refactorize RETURN visit --- arch/zx48k/translator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9855c0613..ca4476d74 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -620,12 +620,11 @@ def visit_IF(self, node): def visit_RETURN(self, node): if len(node.children) == 2: # Something to return? yield node.children[1] - self.emit('ret' + self.TSUFFIX(node.children[1].type_), node.children[1].t, - '%s__leave' % node.children[0].mangled) + self.ic_ret(node.children[1].type_, node.children[1].t, '%s__leave' % node.children[0].mangled) elif len(node.children) == 1: - self.emit('ret', '%s__leave' % node.children[0].mangled) + self.ic_return('%s__leave' % node.children[0].mangled) else: - self.emit('leave', '__fastcall__') + self.ic_leave('__fastcall__') def visit_UNTIL_DO(self, node): loop_label = backend.tmp_label() From 8b9ae7a47c1518ab641e48a5c47196b4667df918 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:01:10 +0200 Subject: [PATCH 46/97] Refactorice UNTIL DO visit --- arch/zx48k/translator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index ca4476d74..ddad44ea3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -632,18 +632,18 @@ def visit_UNTIL_DO(self, node): continue_loop = backend.tmp_label() if node.token == 'UNTIL_DO': - self.emit('jump', continue_loop) + self.ic_jump(continue_loop) - self.emit('label', loop_label) + self.ic_label(loop_label) self.LOOPS.append(('DO', end_loop, continue_loop)) # Saves which labels to jump upon EXIT or CONTINUE if len(node.children) > 1: yield node.children[1] - self.emit('label', continue_loop) + self.ic_label(continue_loop) yield node.children[0] # Condition - self.emit('jzero' + self.TSUFFIX(node.children[0].type_), node.children[0].t, loop_label) - self.emit('label', end_loop) + self.ic_jzero(node.children[0].type_, node.children[0].t, loop_label) + self.ic_label(end_loop) self.LOOPS.pop() # del loop_label, end_loop, continue_loop From bfa625b6a2c224bb8463f4b9ec80c8fb384d4ead Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:09:33 +0200 Subject: [PATCH 47/97] Refactorize WHILE visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index ddad44ea3..4c5f4c988 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -652,15 +652,15 @@ def visit_WHILE(self, node): end_loop = backend.tmp_label() self.LOOPS.append(('WHILE', end_loop, loop_label)) # Saves which labels to jump upon EXIT or CONTINUE - self.emit('label', loop_label) + self.ic_label(loop_label) yield node.children[0] - self.emit('jzero' + self.TSUFFIX(node.children[0].type_), node.children[0].t, end_loop) + self.ic_jzero(node.children[0].type_, node.children[0].t, end_loop) if len(node.children) > 1: yield node.children[1] - self.emit('jump', loop_label) - self.emit('label', end_loop) + self.ic_jump(loop_label) + self.ic_label(end_loop) self.LOOPS.pop() def visit_WHILE_DO(self, node): From 8b0a23d20d0874b53ff5c6ab59c45c1304c61b5e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:11:09 +0200 Subject: [PATCH 48/97] Refactorize PLOT visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 4c5f4c988..3b26ad91a 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -676,10 +676,10 @@ def visit_PLOT(self, node): TMP_HAS_ATTR = self.check_attr(node, 2) yield TMP_HAS_ATTR yield node.children[0] - self.emit('param' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.ic_param(node.children[0].type_, node.children[0].t) yield node.children[1] - self.emit('fparam' + self.TSUFFIX(node.children[1].type_), node.children[1].t) - self.emit('call', 'PLOT', 0) # Procedure call. Discard return + self.ic_fparam(node.children[1].type_, node.children[1].t) + self.ic_call('PLOT', 0) backend.REQUIRES.add('plot.asm') self.HAS_ATTR = (TMP_HAS_ATTR is not None) From c1d7ad3a8f42ed2fd75d4eb162924fb5974f1740 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:14:43 +0200 Subject: [PATCH 49/97] Refactorize DRAW visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 3b26ad91a..6c7582d87 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -687,10 +687,10 @@ def visit_DRAW(self, node): TMP_HAS_ATTR = self.check_attr(node, 2) yield TMP_HAS_ATTR yield node.children[0] - self.emit('param' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.ic_param(node.children[0].type_, node.children[0].t) yield node.children[1] - self.emit('fparam' + self.TSUFFIX(node.children[1].type_), node.children[1].t) - self.emit('call', 'DRAW', 0) # Procedure call. Discard return + self.ic_fparam(node.children[1].type_, node.children[1].t) + self.ic_call('DRAW', 0) backend.REQUIRES.add('draw.asm') self.HAS_ATTR = (TMP_HAS_ATTR is not None) From e0ea1f6f7a5b4e68a1682cd1681ccf61da34874a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:17:48 +0200 Subject: [PATCH 50/97] Refactorize DRAW3 visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 6c7582d87..8bae7c08f 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -698,12 +698,12 @@ def visit_DRAW3(self, node): TMP_HAS_ATTR = self.check_attr(node, 3) yield TMP_HAS_ATTR yield node.children[0] - self.emit('param' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.ic_param(node.children[0].type_, node.children[0].t) yield node.children[1] - self.emit('param' + self.TSUFFIX(node.children[1].type_), node.children[1].t) + self.ic_param(node.children[1].type_, node.children[1].t) yield node.children[2] - self.emit('fparam' + self.TSUFFIX(node.children[2].type_), node.children[2].t) - self.emit('call', 'DRAW3', 0) # Procedure call. Discard return + self.ic_fparam(node.children[2].type_, node.children[2].t) + self.ic_call('DRAW3', 0) backend.REQUIRES.add('draw3.asm') self.HAS_ATTR = (TMP_HAS_ATTR is not None) From 7162ec668417148834dbd27e1b878bb6c23b2b01 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:20:07 +0200 Subject: [PATCH 51/97] Refactorize CIRCLE visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8bae7c08f..b5dd76981 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -711,12 +711,12 @@ def visit_CIRCLE(self, node): TMP_HAS_ATTR = self.check_attr(node, 3) yield TMP_HAS_ATTR yield node.children[0] - self.emit('param' + self.TSUFFIX(node.children[0].type_), node.children[0].t) + self.ic_param(node.children[0].type_, node.children[0].t) yield node.children[1] - self.emit('param' + self.TSUFFIX(node.children[1].type_), node.children[1].t) + self.ic_param(node.children[1].type_, node.children[1].t) yield node.children[2] - self.emit('fparam' + self.TSUFFIX(node.children[2].type_), node.children[2].t) - self.emit('call', 'CIRCLE', 0) # Procedure call. Discard return + self.ic_fparam(node.children[2].type_, node.children[2].t) + self.ic_call('CIRCLE', 0) backend.REQUIRES.add('circle.asm') self.HAS_ATTR = (TMP_HAS_ATTR is not None) From 22c1870cb5ccb3e6f95e89784f0d549f630cf858 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:47:25 +0200 Subject: [PATCH 52/97] Refactorize OUT visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index b5dd76981..9c022a9e3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -729,7 +729,7 @@ def visit_CIRCLE(self, node): def visit_OUT(self, node): yield node.children[0] yield node.children[1] - self.emit('out', node.children[0].t, node.children[1].t) + self.ic_out(node.children[0].t, node.children[1].t) def visit_PRINT(self, node): for i in node.children: From d6be9fd9acab8f1b6ccdfe9c6ea5757224fbf750 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 11:25:38 +0200 Subject: [PATCH 53/97] Refactorize PRINT visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9c022a9e3..8ed43e92c 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -738,8 +738,8 @@ def visit_PRINT(self, node): # Print subcommands (AT, OVER, INK, etc... must be skipped here) if i.token in ('PRINT_TAB', 'PRINT_AT', 'PRINT_COMMA',) + self.ATTR_TMP: continue - self.emit('fparam' + self.TSUFFIX(i.type_), i.t) - self.emit('call', '__PRINT' + self.TSUFFIX(i.type_).upper(), 0) + self.ic_fparam(i.type_, i.t) + self.ic_call('__PRINT' + self.TSUFFIX(i.type_).upper(), 0) backend.REQUIRES.add('print' + self.TSUFFIX(i.type_).lower() + '.asm') for i in node.children: @@ -749,11 +749,11 @@ def visit_PRINT(self, node): if node.eol: if self.HAS_ATTR: - self.emit('call', 'PRINT_EOL_ATTR', 0) + self.ic_call('PRINT_EOL_ATTR', 0) backend.REQUIRES.add('print_eol_attr.asm') self.HAS_ATTR = False else: - self.emit('call', 'PRINT_EOL', 0) + self.ic_call('PRINT_EOL', 0) backend.REQUIRES.add('print.asm') else: self.norm_attr() From 7e3fdb055f2f6a533aaa75ecf5d2fe650fc58e12 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:13:05 +0200 Subject: [PATCH 54/97] Refactorize PRINT_AT visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8ed43e92c..9fac5b7a2 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -760,10 +760,10 @@ def visit_PRINT(self, node): def visit_PRINT_AT(self, node): yield node.children[0] - self.emit('paramu8', node.children[0].t) + self.ic_param(TYPE.ubyte, node.children[0].t) yield node.children[1] - self.emit('fparamu8', node.children[1].t) - self.emit('call', 'PRINT_AT', 0) # Procedure call. Discard return + self.ic_fparam(TYPE.ubyte, node.children[1].t) + self.ic_call('PRINT_AT', 0) # Procedure call. Discard return backend.REQUIRES.add('print.asm') def visit_PRINT_TAB(self, node): From ea19c4b7f5a0fa9692e72094e8a2523ce5cc885a Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:17:23 +0200 Subject: [PATCH 55/97] Refactorize PRINT_TAB visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9fac5b7a2..a529c96f3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -768,8 +768,8 @@ def visit_PRINT_AT(self, node): def visit_PRINT_TAB(self, node): yield node.children[0] - self.emit('fparamu8', node.children[0].t) - self.emit('call', 'PRINT_TAB', 0) + self.ic_fparam(TYPE.ubyte, node.children[0].t) + self.ic_call('PRINT_TAB', 0) backend.REQUIRES.add('print.asm') def visit_PRINT_COMMA(self, node): From d3306134455620a541ffdfe3b17936e03901197d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:17:55 +0200 Subject: [PATCH 56/97] Refactorize PRINT_COMMA visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index a529c96f3..6635b8070 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -773,7 +773,7 @@ def visit_PRINT_TAB(self, node): backend.REQUIRES.add('print.asm') def visit_PRINT_COMMA(self, node): - self.emit('call', 'PRINT_COMMA', 0) + self.ic_call('PRINT_COMMA', 0) backend.REQUIRES.add('print.asm') def visit_LOAD(self, node): From 4ce68a73177901b48af04ddb4a19b6cca5ccdcd0 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:23:09 +0200 Subject: [PATCH 57/97] Refactorize LOAD visit --- arch/zx48k/translator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 6635b8070..62c09c593 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -778,14 +778,14 @@ def visit_PRINT_COMMA(self, node): def visit_LOAD(self, node): yield node.children[0] - self.emit('paramstr', node.children[0].t) + self.ic_param(TYPE.string, node.children[0].t) yield node.children[1] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[1].t) + self.ic_param(gl.PTR_TYPE, node.children[1].t) yield node.children[2] - self.emit('param' + self.TSUFFIX(gl.PTR_TYPE), node.children[2].t) + self.ic_param(gl.PTR_TYPE, node.children[2].t) - self.emit('paramu8', int(node.token == 'LOAD')) - self.emit('call', 'LOAD_CODE', 0) + self.ic_param(TYPE.ubyte, int(node.token == 'LOAD')) + self.ic_call('LOAD_CODE', 0) backend.REQUIRES.add('load.asm') def visit_SAVE(self, node): From 22f826c5ae7f18f6b0ac8e5dbec6080d1e58e6fa Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:27:02 +0200 Subject: [PATCH 58/97] Refactorize SAVE visit --- arch/zx48k/translator.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 62c09c593..9c47abe5b 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -790,12 +790,12 @@ def visit_LOAD(self, node): def visit_SAVE(self, node): yield (node.children[0]) - self.emit('paramstr', node.children[0].t) + self.ic_param(TYPE.string, node.children[0].t) yield (node.children[1]) - self.emit('paramu16', node.children[1].t) - yield (node.children[2]) - self.emit('paramu16', node.children[2].t) - self.emit('call', 'SAVE_CODE', 0) + self.ic_param(gl.PTR_TYPE, node.children[1].t) + yield node.children[2] + self.ic_param(gl.PTR_TYPE, node.children[2].t) + self.ic_call('SAVE_CODE', 0) backend.REQUIRES.add('save.asm') def visit_VERIFY(self, node): From 17b742b943793fe7d88bf1aa753ac91ee84ef77c Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:31:00 +0200 Subject: [PATCH 59/97] Refactorize BORDER visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9c47abe5b..5646fe567 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -803,8 +803,8 @@ def visit_VERIFY(self, node): def visit_BORDER(self, node): yield node.children[0] - self.emit('fparamu8', node.children[0].t) - self.emit('call', 'BORDER', 0) # Procedure call. Discard return + self.ic_fparam(TYPE.ubyte, node.children[0].t) + self.ic_call('BORDER', 0) backend.REQUIRES.add('border.asm') def visit_BEEP(self, node): From 5a54a3b1402c519d51d848c9484729635a49aefb Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:51:14 +0200 Subject: [PATCH 60/97] Refactorize BEEP visit Also adds missing BEEP test --- arch/zx48k/translator.py | 12 ++-- tests/functional/opt1_beep_const.asm | 54 ++++++++++++++ tests/functional/opt1_beep_const.bas | 4 ++ tests/functional/opt1_beep_var.asm | 104 +++++++++++++++++++++++++++ tests/functional/opt1_beep_var.bas | 5 ++ 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 tests/functional/opt1_beep_const.asm create mode 100644 tests/functional/opt1_beep_const.bas create mode 100644 tests/functional/opt1_beep_var.asm create mode 100644 tests/functional/opt1_beep_var.bas diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 5646fe567..042a297bd 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -810,16 +810,16 @@ def visit_BORDER(self, node): def visit_BEEP(self, node): if node.children[0].token == node.children[1].token == 'NUMBER': # BEEP , DE, HL = arch.zx48k.beep.getDEHL(float(node.children[0].t), float(node.children[1].t)) - self.emit('paramu16', HL) - self.emit('fparamu16', DE) - self.emit('call', '__BEEPER', 0) # Procedure call. Discard return + self.ic_param(TYPE.uinteger, HL) + self.ic_fparam(TYPE.uinteger, DE) + self.ic_call('__BEEPER', 0) # Procedure call. Discard return backend.REQUIRES.add('beeper.asm') else: yield node.children[1] - self.emit('paramf', node.children[1].t) + self.ic_param(TYPE.float_, node.children[1].t) yield node.children[0] - self.emit('fparamf', node.children[0].t) - self.emit('call', 'BEEP', 0) # Procedure call. Discard return + self.ic_fparam(TYPE.float_, node.children[0].t) + self.ic_call('BEEP', 0) backend.REQUIRES.add('beep.asm') def visit_PAUSE(self, node): diff --git a/tests/functional/opt1_beep_const.asm b/tests/functional/opt1_beep_const.asm new file mode 100644 index 000000000..4783fa8c2 --- /dev/null +++ b/tests/functional/opt1_beep_const.asm @@ -0,0 +1,54 @@ + org 32768 +__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (__CALL_BACK__), hl + ei + ld hl, 1642 + push hl + ld hl, 261 + call __BEEPER + ld hl, 0 + ld b, h + ld c, l +__END_PROGRAM: + di + ld hl, (__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +__CALL_BACK__: + DEFW 0 +#line 1 "beeper.asm" +; vim:ts=4:et:sw=4: + ; This is a fast beep routine, but needs parameters + ; codified in a different way. +; See http://www.wearmouth.demon.co.uk/zx82.htm#L03F8 + ; Needs pitch on top of the stack + ; HL = duration +__BEEPER: + ex de, hl + pop hl + ex (sp), hl ; CALLEE + push ix ; BEEPER changes IX + call 03B5h + pop ix + ret +#line 22 "opt1_beep_const.bas" +ZXBASIC_USER_DATA: + ; Defines DATA END --> HEAP size is 0 +ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP + ; Defines USER DATA Length in bytes +ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA + END diff --git a/tests/functional/opt1_beep_const.bas b/tests/functional/opt1_beep_const.bas new file mode 100644 index 000000000..ffcbeb12a --- /dev/null +++ b/tests/functional/opt1_beep_const.bas @@ -0,0 +1,4 @@ +' Beep with constants + +BEEP 1, 0.0 + diff --git a/tests/functional/opt1_beep_var.asm b/tests/functional/opt1_beep_var.asm new file mode 100644 index 000000000..31fe9622c --- /dev/null +++ b/tests/functional/opt1_beep_var.asm @@ -0,0 +1,104 @@ + org 32768 +__START_PROGRAM: + di + push ix + push iy + exx + push hl + exx + ld hl, 0 + add hl, sp + ld (__CALL_BACK__), hl + ei + ld a, 000h + ld de, 00000h + ld bc, 00000h + push bc + push de + push af + ld a, (_a) + ld de, (_a + 1) + ld bc, (_a + 3) + call BEEP + ld hl, 0 + ld b, h + ld c, l +__END_PROGRAM: + di + ld hl, (__CALL_BACK__) + ld sp, hl + exx + pop hl + exx + pop iy + pop ix + ei + ret +__CALL_BACK__: + DEFW 0 +#line 1 "beep.asm" +#line 1 "stackf.asm" + ; ------------------------------------------------------------- + ; Functions to manage FP-Stack of the ZX Spectrum ROM CALC + ; ------------------------------------------------------------- + __FPSTACK_PUSH EQU 2AB6h ; Stores an FP number into the ROM FP stack (A, ED CB) + __FPSTACK_POP EQU 2BF1h ; Pops an FP number out of the ROM FP stack (A, ED CB) +__FPSTACK_PUSH2: ; Pushes Current A ED CB registers and top of the stack on (SP + 4) + ; Second argument to push into the stack calculator is popped out of the stack + ; Since the caller routine also receives the parameters into the top of the stack + ; four bytes must be removed from SP before pop them out + call __FPSTACK_PUSH ; Pushes A ED CB into the FP-STACK + exx + pop hl ; Caller-Caller return addr + exx + pop hl ; Caller return addr + pop af + pop de + pop bc + push hl ; Caller return addr + exx + push hl ; Caller-Caller return addr + exx + jp __FPSTACK_PUSH +__FPSTACK_I16: ; Pushes 16 bits integer in HL into the FP ROM STACK + ; This format is specified in the ZX 48K Manual + ; You can push a 16 bit signed integer as + ; 0 SS LL HH 0, being SS the sign and LL HH the low + ; and High byte respectively + ld a, h + rla ; sign to Carry + sbc a, a ; 0 if positive, FF if negative + ld e, a + ld d, l + ld c, h + xor a + ld b, a + jp __FPSTACK_PUSH +#line 2 "beep.asm" +BEEP: ; The beep command, as in BASIC + ; Duration in C,ED,LH (float) + ; Pitch in top of the stack + CALL __FPSTACK_PUSH + pop hl ; RET address + pop af + pop de + pop bc ; Recovers PITCH from the stack + push hl ; CALLEE, now ret addr in top of the stack + CALL __FPSTACK_PUSH ; Pitch onto the FP stack + push ix ; BEEP routine modifies IX. We have to preserve it + call 03F8h + pop ix + ret +#line 28 "opt1_beep_var.bas" +ZXBASIC_USER_DATA: +_a: + DEFB 81h + DEFB 00h + DEFB 00h + DEFB 00h + DEFB 00h + ; Defines DATA END --> HEAP size is 0 +ZXBASIC_USER_DATA_END EQU ZXBASIC_MEM_HEAP + ; Defines USER DATA Length in bytes +ZXBASIC_USER_DATA_LEN EQU ZXBASIC_USER_DATA_END - ZXBASIC_USER_DATA + END diff --git a/tests/functional/opt1_beep_var.bas b/tests/functional/opt1_beep_var.bas new file mode 100644 index 000000000..11d706ffb --- /dev/null +++ b/tests/functional/opt1_beep_var.bas @@ -0,0 +1,5 @@ +' Beep with constants + +DIM a as Float = 1 +BEEP a, 0.0 + From 677bb7a2d247cacf9f815a222d01238c819023b8 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:55:05 +0200 Subject: [PATCH 61/97] Refactorize PAUSE visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 042a297bd..d24be210b 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -824,8 +824,8 @@ def visit_BEEP(self, node): def visit_PAUSE(self, node): yield node.children[0] - self.emit('fparam' + self.TSUFFIX(node.children[0].type_), node.children[0].t) - self.emit('call', '__PAUSE', 0) + self.ic_fparam(node.children[0].type_, node.children[0].t) + self.ic_call('__PAUSE', 0) backend.REQUIRES.add('pause.asm') # endregion From e0e72885eaec2f95610f92b503f522075d6ba04f Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:57:27 +0200 Subject: [PATCH 62/97] Refactorize ATTR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index d24be210b..04bdeae2e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -836,8 +836,8 @@ def visit_PAUSE(self, node): # ----------------------------------------------------------------------- def visit_ATTR_sentence(self, node): yield node.children[0] - self.emit('fparamu8', node.children[0].t) - self.emit('call', node.token, 0) + self.ic_fparam(TYPE.ubyte, node.children[0].t) + self.ic_call(node.token, 0) backend.REQUIRES.add('%s.asm' % node.token.lower()) self.HAS_ATTR = True From cd30ab2e0fbb3370f10534c72b53ff1f51b63680 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 12:59:46 +0200 Subject: [PATCH 63/97] Refactorize ASM visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 04bdeae2e..d7d4a7f64 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -872,7 +872,7 @@ def visit_ITALIC(self, node): # Other Sentences, like ASM, etc.. # ----------------------------------------------------------------------------------------------------- def visit_ASM(self, node): - self.emit('inline', node.asm, node.lineno) + self.ic_inline(node.asm, node.lineno) # endregion From f20001f9f3443a950c8de4b2875d70da75a92638 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 13:03:26 +0200 Subject: [PATCH 64/97] Refactorize helpers --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index d7d4a7f64..0e42be828 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -893,13 +893,13 @@ def emit_var_assign(self, var, t): raise NotImplementedError() if var.scope == SCOPE.global_: - self.emit('store' + self.TSUFFIX(var.type_), var.mangled, t) + self.ic_store(var.type_, var.mangled, t) elif var.scope == SCOPE.parameter: - self.emit('pstore' + self.TSUFFIX(var.type_), p + str(var.offset), t) + self.ic_pstore(var.type_, p + str(var.offset), t) elif var.scope == SCOPE.local: if var.alias is not None and var.alias.class_ == CLASS.array: var.offset -= 1 + 2 * var.alias.count - self.emit('pstore' + self.TSUFFIX(var.type_), p + str(-var.offset), t) + self.ic_pstore(var.type_, p + str(-var.offset), t) def emit_let_left_part(self, node, t=None): var = node.children[0] From 2e995f54a3cbcc626a4dd2cb833449a08e6f8e21 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 19:13:00 +0200 Subject: [PATCH 65/97] Refactorize LABEL visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 0e42be828..60b3b9547 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1047,9 +1047,9 @@ class VarTranslator(TranslatorVisitor): """ def visit_LABEL(self, node): - self.emit('label', node.mangled) + self.ic_label(node.mangled) for tmp in node.aliased_by: - self.emit('label', tmp.mangled) + self.ic_label(tmp.mangled) def visit_VARDECL(self, node): entry = node.entry From 48582c1ecb91938a80c103c22f36bba30234e0d1 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:11:44 +0200 Subject: [PATCH 66/97] Refactorize VARDECL visit --- arch/zx48k/translator.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 60b3b9547..38d532133 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1059,20 +1059,19 @@ def visit_VARDECL(self, node): return if entry.addr is not None: - self.emit('deflabel', entry.mangled, entry.addr) + self.ic_deflabel(entry.mangled, entry.addr) for entry in entry.aliased_by: - self.emit('deflabel', entry.mangled, entry.addr) + self.ic_deflabel(entry.mangled, entry.addr) elif entry.alias is None: for alias in entry.aliased_by: - self.emit('label', alias.mangled) + self.ic_label(alias.mangled) if entry.default_value is None: - self.emit('var', entry.mangled, entry.size) + self.ic_var(entry.mangled, entry.size) else: if isinstance(entry.default_value, symbols.CONST) and entry.default_value.token == 'CONST': - self.emit('varx', node.mangled, self.TSUFFIX(node.type_), - [self.traverse_const(entry.default_value)]) + self.ic_varx(node.mangled, node.type_, [self.traverse_const(entry.default_value)]) else: - self.emit('vard', node.mangled, Translator.default_value(node.type_, entry.default_value)) + self.ic_vard(node.mangled, Translator.default_value(node.type_, entry.default_value)) def visit_ARRAYDECL(self, node): entry = node.entry From 111868c1cf95d1053f0880733215d9a8187c525e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 19:54:45 +0200 Subject: [PATCH 67/97] Refactorize ARRAYDECL visit --- arch/zx48k/translator.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 38d532133..c5f34e2c3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1093,7 +1093,7 @@ def visit_ARRAYDECL(self, node): arr_data = [] if entry.addr: - self.emit('deflabel', data_label, "%s" % entry.addr) + self.ic_deflabel(data_label, "%s" % entry.addr) else: if entry.default_value is not None: arr_data = Translator.array_default_value(node.type_, entry.default_value) @@ -1101,28 +1101,28 @@ def visit_ARRAYDECL(self, node): arr_data = ['00'] * node.size for alias in entry.aliased_by: - offset = 1 + 2 * entry.count + alias.offset # TODO: Generalize for multi-arch - self.emit('deflabel', alias.mangled, '%s + %i' % (entry.mangled, offset)) + offset = 1 + 2 * TYPE.size(gl.PTR_TYPE) + alias.offset # TODO: Generalize for multi-arch + self.ic_deflabel(alias.mangled, '%s + %i' % (entry.mangled, offset)) - self.emit('varx', node.mangled, self.TSUFFIX(gl.PTR_TYPE), [idx_table_label]) + self.ic_varx(node.mangled, gl.PTR_TYPE, [idx_table_label]) if entry.addr: - self.emit('varx', entry.data_ptr_label, self.TSUFFIX(gl.PTR_TYPE), [self.traverse_const(entry.addr)]) + self.ic_varx(entry.data_ptr_label, gl.PTR_TYPE, [self.traverse_const(entry.addr)]) else: - self.emit('varx', entry.data_ptr_label, self.TSUFFIX(gl.PTR_TYPE), [data_label]) - self.emit('vard', data_label, arr_data) + self.ic_varx(entry.data_ptr_label, gl.PTR_TYPE, [data_label]) + self.ic_vard(data_label, arr_data) - self.emit('vard', idx_table_label, l) + self.ic_vard(idx_table_label, l) if entry.lbound_used: l = ['%04X' % len(node.bounds)] + \ ['%04X' % bound.lower for bound in node.bounds] - self.emit('vard', '__LBOUND__.' + entry.mangled, l) + self.ic_vard('__LBOUND__.' + entry.mangled, l) if entry.ubound_used: l = ['%04X' % len(node.bounds)] + \ ['%04X' % bound.upper for bound in node.bounds] - self.emit('vard', '__UBOUND__.' + entry.mangled, l) + self.ic_vard('__UBOUND__.' + entry.mangled, l) class UnaryOpTranslator(TranslatorVisitor): From 25f453b6e902bb06137cc49e40b609c025bc796e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 19:58:44 +0200 Subject: [PATCH 68/97] Refactorize MINUS visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index c5f34e2c3..0a109d35e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1131,7 +1131,7 @@ class UnaryOpTranslator(TranslatorVisitor): def visit_MINUS(self, node): yield node.operand - self.emit('neg' + self.TSUFFIX(node.type_), node.t, node.operand.t) + self.ic_neg(node.type_, node.t, node.operand.t) def visit_NOT(self, node): yield node.operand From 1da28139fe02098f326dd0ddbbf12c1e63ba3248 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 20:10:29 +0200 Subject: [PATCH 69/97] Refactorize NOT visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 0a109d35e..58ec74220 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1135,7 +1135,7 @@ def visit_MINUS(self, node): def visit_NOT(self, node): yield node.operand - self.emit('not' + self.TSUFFIX(node.operand.type_), node.t, node.operand.t) + self.ic_not(node.operand.type_, node.t, node.operand.t) def visit_BNOT(self, node): yield node.operand From ebe4be13fa39009712af9cd97e341522b9adbb74 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 21:14:35 +0200 Subject: [PATCH 70/97] Refactorize BNOT visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 58ec74220..9c82eeea8 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1139,7 +1139,7 @@ def visit_NOT(self, node): def visit_BNOT(self, node): yield node.operand - self.emit('bnot' + self.TSUFFIX(node.operand.type_), node.t, node.operand.t) + self.ic_bnot(node.operand.type_, node.t, node.operand.t) def visit_ADDRESS(self, node): scope = node.children[0].scope From 67949df923485831786e1da06598a5606dec020b Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 21:36:08 +0200 Subject: [PATCH 71/97] Refactorize ADDRESS visit --- arch/zx48k/translator.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9c82eeea8..f6d3221f8 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1147,18 +1147,18 @@ def visit_ADDRESS(self, node): yield node.children[0] # Address of an array element. if scope == SCOPE.global_: - self.emit('aaddr', node.t, node.children[0].entry.mangled) + self.ic_aaddr(node.t, node.children[0].entry.mangled) elif scope == 'parameter': - self.emit('paaddr', node.t, node.children[0].entry.offset) + self.ic_paaddr(node.t, node.children[0].entry.offset) elif scope == 'local': - self.emit('paaddr', node.t, -node.children[0].entry.offset) + self.ic_paaddr(node.t, -node.children[0].entry.offset) else: # It's a scalar variable if scope == SCOPE.global_: - self.emit('load' + self.TSUFFIX(node.type_), node.t, '#' + node.operand.t) + self.ic_load(node.type_, node.t, '#' + node.operand.t) elif scope == SCOPE.parameter: - self.emit('paddr', node.operand.offset + node.operand.type_.size % 2, node.t) + self.ic_paddr(node.operand.offset + node.operand.type_.size % 2, node.t) elif scope == SCOPE.local: - self.emit('paddr', -node.operand.offset, node.t) + self.ic_paddr(-node.operand.offset, node.t) class BuiltinTranslator(TranslatorVisitor): From ac0f40438522a85bdf536e32e50e847c83f72352 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 23:51:28 +0200 Subject: [PATCH 72/97] Refactorize INKEY visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f6d3221f8..9dd841335 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1168,7 +1168,7 @@ class BuiltinTranslator(TranslatorVisitor): # region STRING Functions def visit_INKEY(self, node): - self.emit('call', 'INKEY', Type.string.size) + self.ic_call('INKEY', Type.string.size) backend.REQUIRES.add('inkey.asm') def visit_IN(self, node): From f9c6fd81ca1a794c342f564b9a61fca3e3d1a188 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 23:54:46 +0200 Subject: [PATCH 73/97] Refactorize IN visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9dd841335..57f711a4f 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1172,7 +1172,7 @@ def visit_INKEY(self, node): backend.REQUIRES.add('inkey.asm') def visit_IN(self, node): - self.emit('in', node.children[0].t) + self.ic_in(node.children[0].t) def visit_CODE(self, node): self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.operand.t) From 38af9bf8fb7b40a29d85d2d859d771660e8a35e3 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sat, 27 Jul 2019 23:59:52 +0200 Subject: [PATCH 74/97] Refactorize CODE visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 57f711a4f..56c67d5e3 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1175,13 +1175,13 @@ def visit_IN(self, node): self.ic_in(node.children[0].t) def visit_CODE(self, node): - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.operand.t) + self.ic_fparam(gl.PTR_TYPE, node.operand.t) if node.operand.token != 'STRING' and node.operand.token != 'VAR' and node.operand.t != '_': - self.emit('fparamu8', 1) # If the argument is not a variable, it must be freed + self.ic_fparam(TYPE.ubyte, 1) # If the argument is not a variable, it must be freed else: - self.emit('fparamu8', 0) + self.ic_fparam(TYPE.ubyte, 0) - self.emit('call', '__ASC', Type.ubyte.size) # Expect a char code + self.ic_call('__ASC', Type.ubyte.size) # Expect a char code backend.REQUIRES.add('asc.asm') def visit_CHR(self, node): From 94a53e4f35127c46105e4218f55bafce27b252b3 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:02:56 +0200 Subject: [PATCH 75/97] Refactorize CHR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 56c67d5e3..8cba389d2 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1185,8 +1185,8 @@ def visit_CODE(self, node): backend.REQUIRES.add('asc.asm') def visit_CHR(self, node): - self.emit('fparam' + self.TSUFFIX(gl.STR_INDEX_TYPE), len(node.operand)) # Number of args - self.emit('call', 'CHR', node.size) + self.ic_fparam(gl.STR_INDEX_TYPE, len(node.operand)) # Number of args + self.ic_call('CHR', node.size) backend.REQUIRES.add('chr.asm') def visit_STR(self, node): From 81fdd58263589014bc1559f962147505bc104bdf Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:05:08 +0200 Subject: [PATCH 76/97] Refactorize STR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8cba389d2..ce9d94177 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1190,8 +1190,8 @@ def visit_CHR(self, node): backend.REQUIRES.add('chr.asm') def visit_STR(self, node): - self.emit('fparamf', node.children[0].t) - self.emit('call', '__STR_FAST', node.type_.size) + self.ic_fparam(TYPE.float_, node.children[0].t) + self.ic_call('__STR_FAST', node.type_.size) backend.REQUIRES.add('str.asm') def visit_LEN(self, node): From 7fdd3ba3aaa3ae8acc8eaed210328bc1b21e1e0d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:09:45 +0200 Subject: [PATCH 77/97] Refactorize LEN visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index ce9d94177..040bc0591 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1195,7 +1195,7 @@ def visit_STR(self, node): backend.REQUIRES.add('str.asm') def visit_LEN(self, node): - self.emit('lenstr', node.t, node.operand.t) + self.ic_lenstr(node.t, node.operand.t) def visit_VAL(self, node): self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.operand.t) From c30015d3d1cc73ef4190f4fc8ba4e70f70e684a9 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:22:34 +0200 Subject: [PATCH 78/97] Refactorize VAR visit --- arch/zx48k/translator.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 040bc0591..9ed48927e 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1198,13 +1198,13 @@ def visit_LEN(self, node): self.ic_lenstr(node.t, node.operand.t) def visit_VAL(self, node): - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.operand.t) + self.ic_fparam(gl.PTR_TYPE, node.operand.t) if node.operand.token not in ('STRING', 'VAR') and node.operand.t != '_': - self.emit('fparamu8', 1) # If the argument is not a variable, it must be freed + self.ic_fparam(TYPE.ubyte, 1) # If the argument is not a variable, it must be freed else: - self.emit('fparamu8', 0) + self.ic_fparam(TYPE.ubyte, 0) - self.emit('call', 'VAL', node.type_.size) + self.ic_call('VAL', node.type_.size) backend.REQUIRES.add('val.asm') def visit_ABS(self, node): From 03ef5dbcd02dd33c3206acb8aca55ce46174c406 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:24:59 +0200 Subject: [PATCH 79/97] Refactorize ABS visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 9ed48927e..bbc41af35 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1208,7 +1208,7 @@ def visit_VAL(self, node): backend.REQUIRES.add('val.asm') def visit_ABS(self, node): - self.emit('abs' + self.TSUFFIX(node.children[0].type_), node.t, node.children[0].t) + self.ic_abs(node.children[0].type_, node.t, node.children[0].t) def visit_RND(self, node): # A special "ZEROARY" function with no parameters self.emit('call', 'RND', Type.float_.size) From 31e0b2a403e5365d5fa163b91edba08881631521 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:25:48 +0200 Subject: [PATCH 80/97] Refactorize RND visit --- arch/zx48k/translator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index bbc41af35..763f523f1 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1211,7 +1211,7 @@ def visit_ABS(self, node): self.ic_abs(node.children[0].type_, node.t, node.children[0].t) def visit_RND(self, node): # A special "ZEROARY" function with no parameters - self.emit('call', 'RND', Type.float_.size) + self.ic_call('RND', Type.float_.size) backend.REQUIRES.add('random.asm') # endregion From fc9bf55703997c47f6a1271ac99eb7374e25a4b1 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:35:24 +0200 Subject: [PATCH 81/97] Refactorize PEEK visit Also move region mark --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 763f523f1..2e7822a54 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1207,6 +1207,8 @@ def visit_VAL(self, node): self.ic_call('VAL', node.type_.size) backend.REQUIRES.add('val.asm') + # endregion + def visit_ABS(self, node): self.ic_abs(node.children[0].type_, node.t, node.children[0].t) @@ -1214,10 +1216,8 @@ def visit_RND(self, node): # A special "ZEROARY" function with no parameters self.ic_call('RND', Type.float_.size) backend.REQUIRES.add('random.asm') - # endregion - def visit_PEEK(self, node): - self.emit('load' + self.TSUFFIX(node.type_), node.t, '*' + str(node.children[0].t)) + self.ic_load(node.type_, node.t, '*' + str(node.children[0].t)) # region MATH Functions def visit_SIN(self, node): From 89f6d191c0b5bb37077e080875f4d8da819d45b0 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:38:16 +0200 Subject: [PATCH 82/97] Refactorize SIN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 2e7822a54..832088169 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1221,8 +1221,8 @@ def visit_PEEK(self, node): # region MATH Functions def visit_SIN(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'SIN', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('SIN', node.size) self.REQUIRES.add('sin.asm') def visit_COS(self, node): From bea2800de244e745346534960c437c1d8b9d0947 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:40:46 +0200 Subject: [PATCH 83/97] Refactorize COS visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 832088169..0a1e6397b 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1226,8 +1226,8 @@ def visit_SIN(self, node): self.REQUIRES.add('sin.asm') def visit_COS(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'COS', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('COS', node.size) self.REQUIRES.add('cos.asm') def visit_TAN(self, node): From 4becfa851c19f5966cde03da2f30a13905e4b07b Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 00:42:41 +0200 Subject: [PATCH 84/97] Refactorize TAN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 0a1e6397b..a43111d04 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1231,8 +1231,8 @@ def visit_COS(self, node): self.REQUIRES.add('cos.asm') def visit_TAN(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'TAN', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('TAN', node.size) self.REQUIRES.add('tan.asm') def visit_ASN(self, node): From 19318142e720db2eb8e2001eaff026e98aa9122d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:47:41 +0200 Subject: [PATCH 85/97] Refactorize ASN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index a43111d04..aa9d8ee4d 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1236,8 +1236,8 @@ def visit_TAN(self, node): self.REQUIRES.add('tan.asm') def visit_ASN(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'ASIN', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('ASIN', node.size) self.REQUIRES.add('asin.asm') def visit_ACS(self, node): From 8e5727e79156a04a8fca80e4aa8fb3195aeeb466 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:48:26 +0200 Subject: [PATCH 86/97] Refactorize ACS visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index aa9d8ee4d..2a324d8c4 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1241,8 +1241,8 @@ def visit_ASN(self, node): self.REQUIRES.add('asin.asm') def visit_ACS(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'ACOS', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('ACOS', node.size) self.REQUIRES.add('acos.asm') def visit_ATN(self, node): From f730e1006d44ae7cc13c86d0824de468a4a3bab8 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:48:43 +0200 Subject: [PATCH 87/97] Refactorize ATN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 2a324d8c4..8e23f4fb8 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1246,8 +1246,8 @@ def visit_ACS(self, node): self.REQUIRES.add('acos.asm') def visit_ATN(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'ATAN', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('ATAN', node.size) self.REQUIRES.add('atan.asm') def visit_EXP(self, node): From 1accf6a712ad135618890493b1909ebde19aa1ac Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:48:59 +0200 Subject: [PATCH 88/97] Refactorize EXP visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 8e23f4fb8..fc6990e64 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1251,8 +1251,8 @@ def visit_ATN(self, node): self.REQUIRES.add('atan.asm') def visit_EXP(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'EXP', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('EXP', node.size) self.REQUIRES.add('exp.asm') def visit_LN(self, node): From dcb180ccff4856e9c97e24ae7a73970e0e9daf38 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:49:48 +0200 Subject: [PATCH 89/97] Refactorize LN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index fc6990e64..f1e6d1d69 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1256,8 +1256,8 @@ def visit_EXP(self, node): self.REQUIRES.add('exp.asm') def visit_LN(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'LN', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('LN', node.size) self.REQUIRES.add('logn.asm') def visit_SGN(self, node): From 2563efc06ddc65413d726d18bea749cbf2271aad Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:50:07 +0200 Subject: [PATCH 90/97] Refactorize SGN visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f1e6d1d69..f8a551f20 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1262,8 +1262,8 @@ def visit_LN(self, node): def visit_SGN(self, node): s = self.TSUFFIX(node.operand.type_) - self.emit('fparam' + s, node.operand.t) - self.emit('call', '__SGN%s' % s.upper(), node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('__SGN%s' % s.upper(), node.size) self.REQUIRES.add('sgn%s.asm' % s) def visit_SQR(self, node): From 3ccd911c7c5a2f1c8e35df8b4c5eee7b2439b31c Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 13:50:21 +0200 Subject: [PATCH 91/97] Refactorize SQR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f8a551f20..564ad72ed 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1267,8 +1267,8 @@ def visit_SGN(self, node): self.REQUIRES.add('sgn%s.asm' % s) def visit_SQR(self, node): - self.emit('fparam' + self.TSUFFIX(node.operand.type_), node.operand.t) - self.emit('call', 'SQRT', node.size) + self.ic_fparam(node.operand.type_, node.operand.t) + self.ic_call('SQRT', node.size) self.REQUIRES.add('sqrt.asm') # endregion From e6bc2b1df29e1e6f1452978562b8dff8d1b6653e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 17:08:12 +0200 Subject: [PATCH 92/97] Refactorize LBOUND visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 564ad72ed..731b7a681 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1275,10 +1275,10 @@ def visit_SQR(self, node): def visit_LBOUND(self, node): entry = node.operands[0] - self.emit('param' + self.TSUFFIX(gl.BOUND_TYPE), '#__LBOUND__.' + entry.mangled) + self.ic_param(gl.BOUND_TYPE, '#__LBOUND__.' + entry.mangled) yield node.operands[1] - self.emit('fparam' + self.TSUFFIX(gl.BOUND_TYPE), optemps.new_t()) - self.emit('call', '__BOUND', self.TYPE(gl.BOUND_TYPE).size) + self.ic_fparam(gl.BOUND_TYPE, optemps.new_t()) + self.ic_call('__BOUND', self.TYPE(gl.BOUND_TYPE).size) backend.REQUIRES.add('bound.asm') def visit_UBOUND(self, node): From 6e643bdcc74514ffcc339ac32e88d1c30b233563 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 17:08:29 +0200 Subject: [PATCH 93/97] Refactorize UBOUND visit --- arch/zx48k/translator.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 731b7a681..1abec288c 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1283,10 +1283,10 @@ def visit_LBOUND(self, node): def visit_UBOUND(self, node): entry = node.operands[0] - self.emit('param' + self.TSUFFIX(gl.BOUND_TYPE), '#__UBOUND__.' + entry.mangled) + self.ic_param(gl.BOUND_TYPE, '#__UBOUND__.' + entry.mangled) yield node.operands[1] - self.emit('fparam' + self.TSUFFIX(gl.BOUND_TYPE), optemps.new_t()) - self.emit('call', '__BOUND', self.TYPE(gl.BOUND_TYPE).size) + self.ic_fparam(gl.BOUND_TYPE, optemps.new_t()) + self.ic_call('__BOUND', self.TYPE(gl.BOUND_TYPE).size) backend.REQUIRES.add('bound.asm') def visit_USR_STR(self, node): From 79b8f515da28edccd0083a9e29506a135a009371 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 17:11:08 +0200 Subject: [PATCH 94/97] Refactorize USR_STR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 1abec288c..5d04b6b3b 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1291,8 +1291,8 @@ def visit_UBOUND(self, node): def visit_USR_STR(self, node): # USR ADDR - self.emit('fparamstr', node.children[0].t) - self.emit('call', 'USR_STR', node.type_.size) + self.ic_fparam(TYPE.string, node.children[0].t) + self.ic_call('USR_STR', node.type_.size) backend.REQUIRES.add('usr_str.asm') def visit_USR(self, node): From a6ca1434a98759154c4f90b4d363f44d69073e18 Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 17:13:55 +0200 Subject: [PATCH 95/97] Refactorize USR visit --- arch/zx48k/translator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 5d04b6b3b..91946c99d 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1298,8 +1298,8 @@ def visit_USR_STR(self, node): def visit_USR(self, node): """ Machine code call from basic """ - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), node.children[0].t) - self.emit('call', 'USR', node.type_.size) + self.ic_fparam(gl.PTR_TYPE, node.children[0].t) + self.ic_call('USR', node.type_.size) backend.REQUIRES.add('usr.asm') From bd96b393fb78017a716cfcf71aea9fd0b7065d2d Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Sun, 28 Jul 2019 20:49:24 +0200 Subject: [PATCH 96/97] Refactorize FUNCTION visit --- arch/zx48k/translator.py | 53 ++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index 91946c99d..f1ee190db 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1323,11 +1323,11 @@ def start(self): self.visit(f) def visit_FUNCTION(self, node): - self.emit('label', node.mangled) + self.ic_label(node.mangled) if node.convention == CONVENTION.fastcall: - self.emit('enter', '__fastcall__') + self.ic_enter('__fastcall__') else: - self.emit('enter', node.locals_size) + self.ic_enter(node.locals_size) for local_var in node.local_symbol_table.values(): if not local_var.accessed: # HINT: This should never happens as values() is already filtered @@ -1347,23 +1347,22 @@ def visit_FUNCTION(self, node): r = [] if local_var.default_value is not None: r.extend(self.array_default_value(local_var.type_, local_var.default_value)) - self.emit('larrd', local_var.offset, q, local_var.size, r) # Initializes array bounds + self.ic_larrd(local_var.offset, q, local_var.size, r) # Initializes array bounds elif local_var.class_ == CLASS.const: continue else: # Local vars always defaults to 0, so if 0 we do nothing if local_var.default_value is not None and local_var.default_value != 0: if isinstance(local_var.default_value, symbols.CONST) and \ local_var.default_value.token == 'CONST': - self.emit('lvarx', local_var.offset, self.TSUFFIX(local_var.type_), - [self.traverse_const(local_var.default_value)]) + self.ic_lvarx(local_var.type_, local_var.offset, [self.traverse_const(local_var.default_value)]) else: q = self.default_value(local_var.type_, local_var.default_value) - self.emit('lvard', local_var.offset, q) + self.ic_lvard(local_var.offset, q) for i in node.body: yield i - self.emit('label', '%s__leave' % node.mangled) + self.ic_label('%s__leave' % node.mangled) # Now free any local string from memory. preserve_hl = False @@ -1374,11 +1373,11 @@ def visit_FUNCTION(self, node): if scope == SCOPE.local or (scope == SCOPE.parameter and not local_var.byref): if not preserve_hl: preserve_hl = True - self.emit('exchg') + self.ic_exchg() offset = -local_var.offset if scope == SCOPE.local else local_var.offset - self.emit('fploadstr', local_var.t, offset) - self.emit('call', '__MEM_FREE', 0) + self.ic_fpload(TYPE.string, local_var.t, offset) + self.ic_call('__MEM_FREE', 0) self.REQUIRES.add('free.asm') elif local_var.class_ == CLASS.const: continue @@ -1386,45 +1385,41 @@ def visit_FUNCTION(self, node): if scope == SCOPE.local or (scope == SCOPE.parameter and not local_var.byref): if not preserve_hl: preserve_hl = True - self.emit('exchg') + self.ic_exchg() - self.emit('param' + self.TSUFFIX(gl.BOUND_TYPE), local_var.count) + self.ic_param(gl.BOUND_TYPE, local_var.count) t2 = optemps.new_t() if scope == SCOPE.parameter: - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, - '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t2, '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) elif scope == SCOPE.local: - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, - '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), t2) - self.emit('call', '__ARRAYSTR_FREE_MEM', 0) # frees all the strings and the array itself + self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_fparam(gl.PTR_TYPE, t2) + self.ic_call('__ARRAYSTR_FREE_MEM', 0) self.REQUIRES.add('arraystrfree.asm') if local_var.class_ == CLASS.array and local_var.type_ != self.TYPE(TYPE.string) and \ (scope == SCOPE.local or (scope == SCOPE.parameter and not local_var.byref)): if not preserve_hl: preserve_hl = True - self.emit('exchg') + self.ic_exchg() t2 = optemps.new_t() if scope == SCOPE.parameter: - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, '%i' - % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t2, '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) elif scope == SCOPE.local: - self.emit('pload%s' % self.TSUFFIX(gl.PTR_TYPE), t2, '%i' - % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - self.emit('fparam' + self.TSUFFIX(gl.PTR_TYPE), t2) - self.emit('call', '__MEM_FREE', 0) + self.ic_fparam(gl.PTR_TYPE, t2) + self.ic_call('__MEM_FREE', 0) self.REQUIRES.add('free.asm') if preserve_hl: - self.emit('exchg') + self.ic_exchg() if node.convention == CONVENTION.fastcall: - self.emit('leave', CONVENTION.to_string(node.convention)) + self.ic_leave(CONVENTION.to_string(node.convention)) else: - self.emit('leave', node.params.size) + self.ic_leave(node.params.size) def visit_FUNCDECL(self, node): """ Nested scope functions From 4cc56644d113089f0494db83dc5e39f63490678e Mon Sep 17 00:00:00 2001 From: Jose Rodriguez Date: Mon, 29 Jul 2019 00:11:12 +0200 Subject: [PATCH 97/97] Refactorize duplicated code --- arch/zx48k/translator.py | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/arch/zx48k/translator.py b/arch/zx48k/translator.py index f1ee190db..e1c9bbd33 100644 --- a/arch/zx48k/translator.py +++ b/arch/zx48k/translator.py @@ -1148,9 +1148,9 @@ def visit_ADDRESS(self, node): # Address of an array element. if scope == SCOPE.global_: self.ic_aaddr(node.t, node.children[0].entry.mangled) - elif scope == 'parameter': + elif scope == SCOPE.parameter: self.ic_paaddr(node.t, node.children[0].entry.offset) - elif scope == 'local': + elif scope == SCOPE.local: self.ic_paaddr(node.t, -node.children[0].entry.offset) else: # It's a scalar variable if scope == SCOPE.global_: @@ -1316,6 +1316,14 @@ def __init__(self, function_list): assert isinstance(x, symbols.FUNCTION) self.functions = function_list + def _local_array_load(self, scope, local_var): + t2 = optemps.new_t() + if scope == SCOPE.parameter: + self.ic_pload(gl.PTR_TYPE, t2, '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + elif scope == SCOPE.local: + self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) + self.ic_fparam(gl.PTR_TYPE, t2) + def start(self): while self.functions: f = self.functions.pop(0) @@ -1388,12 +1396,7 @@ def visit_FUNCTION(self, node): self.ic_exchg() self.ic_param(gl.BOUND_TYPE, local_var.count) - t2 = optemps.new_t() - if scope == SCOPE.parameter: - self.ic_pload(gl.PTR_TYPE, t2, '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - elif scope == SCOPE.local: - self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - self.ic_fparam(gl.PTR_TYPE, t2) + self._local_array_load(scope, local_var) self.ic_call('__ARRAYSTR_FREE_MEM', 0) self.REQUIRES.add('arraystrfree.asm') @@ -1403,13 +1406,7 @@ def visit_FUNCTION(self, node): preserve_hl = True self.ic_exchg() - t2 = optemps.new_t() - if scope == SCOPE.parameter: - self.ic_pload(gl.PTR_TYPE, t2, '%i' % (local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - elif scope == SCOPE.local: - self.ic_pload(gl.PTR_TYPE, t2, '%i' % -(local_var.offset - self.TYPE(gl.PTR_TYPE).size)) - - self.ic_fparam(gl.PTR_TYPE, t2) + self._local_array_load(scope, local_var) self.ic_call('__MEM_FREE', 0) self.REQUIRES.add('free.asm')